Post

Retrospective of Kakao Impact

My team and I won the technology innovation award from Kakao Impact. Kakao Impact is a project aimed at solving social issues around us.

Retrospective of Kakao Impact

1. Overview

We proposed the project called “Solar-See”. “Solar-See” is an AI-based game and mapping service developed to identify non-metered solar panels and improve the accuracy of power demand forecasting.

GitHub Repository

Demo

Presentation

2. My role and Responsibilities

I developed both the frontend(React) and backend(Django), deployed the services(Nginx), and fine-tuned an image segmentation model(Ultralytics YOLO11).

3. Architecture

3.1. Training Model

flowchart TD
    A[National Geographic Information Institute] -->|Aerial Photos| B[GPU Server]

3.2. Pre Processing

flowchart TD
    A[National Geographic Information Institute] -->|Aerial Photos| B[Trained AI Model]
    A[National Geographic Information Institute] -->|Metadata| C[Coordinate Converter]
    B[Trained AI Model] -->|Solar panel x,y pixel coordinates on photos| C[Coordinate Converter]
    C[Coordinate Converter] -->|Solar panel longitude, latitude| E[Database; SQLite]

3.3. Service

flowchart TD
    A[Client] <-->  B
    subgraph Personal Server
        B[Nginx] <--> C[Bundled Frontend Files]
        B <--> D[Gunicorn]
        D <--> E[Django]
        E <--> F[SQLite]
        B <--> G[Aerial Images]
    end

4. Tech Stacks

We chose React and Django + Django REST Framework because our team is already familiar with these technologies. We saved over 50GB of images for training the model and developing the service.

4.1. Django REST Framework

Pros:

  • Many AI modules are available in Python
  • Built-in ORM (Django ORM) and built-in JSON conversion (serializers)
  • Auto-generated admin panel.

Cons:

  • Limited flexibility

4.2. Nginx

  • Its asynchronous, event-driven architecture makes it highly efficient at handling concurrent connections. It’s especially fast at serving static files.

4.2.1. High-level features (HTTP optimizations)

1. gzip / brotli – Compression

These compress your static files (like HTML, CSS, JS) before sending them to the browser.
Smaller file size = faster loading.
brotli is newer and usually compresses better than gzip.

2. ETag – File version checker
It’s like a unique ID for each version of a file.
If the file hasn’t changed, the browser can use the cached version instead of downloading again.

3. Last-Modified – Timestamp of the file
The browser asks: “Has this file been updated since last time?”
If not, the server just says “No need to re-download” (sends 304 Not Modified).

4.2.2. Low-level features (System-level speed boosts)

1. sendfile – Skip the middle step
Normally, files go from disk → memory → network.
With sendfile, the OS sends the file directly from disk to network.
This saves time and CPU.

2. mmap – Map file into memory
Makes file access much faster by mapping it directly into memory.
Useful when serving the same files repeatedly.

3. zero-copy I/O – No copying at all
It avoids copying data between parts of the system (like memory and disk).

4.3. SQLite

Pros:

  • Django supports SQLite as the default database.

  • It’s lightweight and file-based, making it easy to share data.

Cons:

  • Lacks concurrency support. Only one process can modify the database at a time.

  • As a serverless RDBMS, it cannot be accessed directly from external networks.

4.4. Ultralytics

Pros:

  • If the training data is well-labeled, fine-tuning can be done easily with just a few commands.
  • This framework has good pre-trained models.

4.4.1. How to fine-turn model?

To be written…

5. Gunicorn?? It’s weird for me.

This was my first time using Django, and I initially didn’t understand why a separate component like Gunicorn was needed for deployment. In Node.js, I was used to creating standalone HTTP servers, so simply porting it behind Nginx was enough.

However, Django introduces a unique concept: the separation between the WSGI (Web Server Gateway Interface) server and the WSGI(web server gateway interface) application

5.1. WSGI Server, WSGI Application

  • The WSGI application handles business logic.

  • The WSGI server is responsible for multiprocessing and threading.

This separation of concerns is a good design principle. It allows the WSGI application to be swapped out easily (e.g., from WSGI to ASGI).

5.2. Node.js vs Django + DRF

For example, if you want to use HTTP/2 in Node.js, you’d need to import the http2 module and change the code accordingly. In Django, on the other hand, you just need to switch the WSGI server.

 Node.jsDjango
Self-HTTP ServerO (default built-in)X (external server required)
Design PhilosophyServer + Runtime All-in-OneApp Logic Only, Server is Needed
Deploymentsimple and low flexibilitycomplex and high flexibility

5.3. Spring Boot Application vs Django

ConceptSpring Boot ApplicationDjango
Web ApplicationSpring Boot applicationDjango project
Web Server / HTTP HandlerEmbedded Tomcat (included by default)External Gunicorn (requires separate setup)
Request Handling & RoutingTomcat receives HTTP requests and forwards them to SpringGunicorn receives HTTP requests and forwards them to Django
Replaceable?Can be replaced with Jetty, Undertow, etc.Can be replaced with uWSGI, Daphne, etc.

6. Points to improve

The project ended with the development of an MVP without considering scenarios with many users. If there are many users, each service will be converted into a container and the following architecture will be considered:

  • SQLite → MySQL: Because SQLite cannot handle multiple file writing
  • Two servers: At least two servers are needed to prevent server downtime
flowchart TD
    A[Client Request] --> N[Nginx]

    N --> C1
    N --> C2
    N --> C3[Bundled Frontend Files]

    subgraph Container_1 [Uvicorn Container 1]
        C1[Uvicorn Instance 1]
        C1 --> W1[ASGI Worker]
        W1 --> D1[Django ASGI App]
    end

    subgraph Container_2 [Uvicorn Container 2]
        C2[Uvicorn Instance 2]
        C2 --> W2[ASGI Worker]
        W2 --> D2[Django ASGI App]
    end

    D1 --> E1[Database Server]
    D2 --> E1[Database Server]

This post is licensed under CC BY 4.0 by the author.