A simple CRUD API to model power grid components and IoT devices measuring power consumption.
The application was written as the solution to a programming challenge. The original formulation of the challenge can be found in REQUIREMENTS.md.
A documentation of the development process and the decisions made in the process can be found in DEVLOG.md.
Tech Stack: FastAPI, SQLAlchemy, PostgreSQL, Docker.
-
Install cargo (for uv): https://www.rust-lang.org/tools/install
-
Install uv: https://docs.astral.sh/uv/getting-started/installation/
-
Clone the repository:
git clone https://github.com/alvarotroya/gridwatch
- Navigate to the project directory:
cd gridwatch
- Set up dev environment:
uv python install 3.12
uv venv
source .venv/bin/activate
- Install pre-commit hooks (optional):
pre-commit install --hook-type pre-commit --hook-type pre-push
- Set up database credentials
cp .env-example .env
- Start the database
docker-compose up -d
- Start the server
fastapi dev gridwatch/main.py
- Visit the OpenAPI documentation at localhost:8000/docs.
-
Profile the endpoints using yappi.
-
Load-test the
POST
measurements endpoint using Locust. -
Use Celery and RabbitMQ/Redis to process measurements asynchronously via a queue.
-
Measure latency:
- From the moment the measurement is made
- To the moment the measurement is sent and placed into the queue.
- To the moment the measurement is picked up from the queue.
- To the moment the measurement persisted on the DB.
-
Questions to answer:
- How well can a single server instance handle the load?
- How well can a single server running the application in multiple threads handle the load?
- How well can multiple servers (2, 3, 4, ...) running behind a load balancer handle the load? Does the database become the bottleneck at some point?
- How well can a single server and the same setup handle the load when queueing measurements for writes instead of persisiting them directly?
- How does latency change between both setups?