Backend & systems engineerRajasthan, India
Sagar Tailor
Builds the layer underneath. Software is strata — users touch the top, and almost nobody sees the scheduler, the lock, the migration, the trace. Those are the ones I build.
github.com/slazyverse ↗·Every claim on this site resolves to a source.
Position
I work on the partsother work depends on
Two projects, and in both of them the same job: build the substrate, then make it observable.
In deadlockd that meant a Go engine where the safety check copies system state under mutex and releases the lock before running its search, and where cycle detection uses an explicit-stack DFS instead of recursion. Correctness is the product; the visualiser exists so the correctness can be watched.
In VAYU-DRISHTI, a four-person satellite air-quality platform, it meant owning the layer everyone else built on — an application factory, async SQLAlchemy over asyncpg, Alembic migrations enabling PostGIS, structlog request tracing, a container environment, and the dashboard that turned the team’s models into something a person could read.
The habit connecting them is writing the reasoning down. Complexity bounds live in function headers. Dependencies carry a line explaining why they exist and why the alternative was rejected. The config layer refuses to start the server in a dangerous state rather than trusting that nobody will ask it to.
The descent
One request,all the way down
Keep scrolling. Every layer is a real one, and the last is four lines of Go that decide whether the whole thing is correct.
00 Surface — A process asks for a resource
This is all a user ever sees: a request, and an answer. Granted or refused, in a few milliseconds.
P1 requests R0 ×1. → GRANTED
deadlockd.vercel.app
01 Interface — It becomes a frame on a socket
The click is serialised and pushed over a WebSocket to the Go engine. The browser now waits.
{ "type": "REQUEST",. "pid": 1,. "rid": 0,. "qty": 1 }
frontend/app/hooks/useDeadlockSocket.ts
02 Engine — The engine refuses to guess
The allocation is applied tentatively, then tested: is there still an order in which every process can finish?
sim.ProcessManualRequest(1, 0, 1). → tentatively allocate. → IsSafeState(state)?. → commit or rollback
backend/engine/manager.go
03 Substrate — And it holds the lock for four lines
The matrices are copied under the mutex and the lock is released. The O(P²·R) search runs on the snapshot, blocking nobody.
state.Mu.Lock(). copy(need[i], state.Need[i]). copy(alloc[i], state.Allocation[i]). state.Mu.Unlock(). // the search begins here
backend/engine/banker.go:L15–L30
01Case study
A real-time deadlock simulator and concurrency visualiser.
Sole author — 6 of 6 commits
A Go backend runs the simulation; a Next.js client renders the resource-allocation graph live over a WebSocket bridge. Processes request and release resources, the engine checks whether each request leaves the system in a safe state, and when a circular wait closes the graph locks and the cycle is recovered and displayed.
The correctness is the product. The visualiser exists so the correctness can be observed — which is the only reason the frontend is there at all.
- Stack
- Go · Next.js · TypeScript
- Licence
- MIT
- Built
- April 2026
func IsSafeState(state *SystemState) (bool, []int) { state.Mu.Lock() np := len(state.Processes) nr := len(state.Resources) work := make([]int, nr) copy(work, state.Available) for i := 0; i < np; i++ { copy(need[i], state.Need[i]) copy(alloc[i], state.Allocation[i]) } state.Mu.Unlock()The safety search
Banker's Algorithm executing at your pace. Scroll to step it forward; scroll back to step it back.
| Need | Allocation | ||
|---|---|---|---|
| P0 | 743 | 010 | finished |
| P1 | 122 | 200 | finished |
| P2 | 000 | 302 | finished |
| P3 | 011 | 211 | finished |
All four processes can finish. The state is safe.
What it does, and where that is proven
The safety check copies system state under mutex, then releases the lock before running its O(P²·R) search — so the expensive computation never blocks other goroutines.
Cycle detection uses an explicit-stack iterative DFS with white/gray/black colouring rather than recursion, so deep process graphs carry no stack-depth risk — and it recovers the actual cycle through a parent array.
Tests assert exact matrix state, not that the code merely ran: a granted safe request must move Available, Allocation and Need to specific expected values.
CI runs go mod verify and the full Go test suite, plus an independent frontend production build, on every push and pull request.
- Commits mine
- 6/6
- Sole contributor
- Safety search
- O(P²·R)
- Documented in-header
- CI gates
- 2
- Go tests · frontend build
- Engine modules
- 8
02Case study
VAYU-DRISHTI
A satellite air-quality platform for India — surface AQI, formaldehyde hotspots and active-fire monitoring.
Team of four — platform layer mine
A four-person project analysing Sentinel-5P and ERA5 observations to estimate ground-level air quality. Yeshika owns the machine-learning pipeline; Soumyadeb owns the AQI calculation and Earth Engine ingestion.
I own the platform: the API, the data layer, the observability, the container environment, and the dashboard the team's models are seen through. Three commits, roughly 11,700 lines across 116 files — the substrate everything else runs on.
- Stack
- FastAPI · PostGIS · Streamlit
- Team
- 4 contributors
- Built
- July 2026
One request, descending
A single request ID threading through every layer — which is what makes an incident traceable rather than guesswork.
CORS + request-ID middleware
app/main.py
{"event":"request.start","request_id":"8f3c1a7e","path":"/api/v1/aqi"}Versioned router
app/api/v1/router.py
Endpoint handler
app/api/v1/endpoints/aqi.py
{"event":"aqi.request","request_id":"8f3c1a7e","bbox":"68,8,97,37"}Service layer
app/services/aqi_service.py
{"event":"aqi.query","request_id":"8f3c1a7e","stations":142}Async session
app/db/session.py
{"event":"db.execute","request_id":"8f3c1a7e","ms":11.4}PostgreSQL + PostGIS
asyncpg
200 OK — every log line above carries request_id 8f3c1a7e
What it does, and where that is proven
Configuration refuses to boot the server on DEBUG=True with ENVIRONMENT=production. The misconfiguration raises at import time, before the application accepts a single request.
Request-ID middleware binds a UUID into structlog contextvars, so every log line emitted during a request carries the same trace ID — and the ID returns to the caller on the X-Request-ID header.
Alembic runs migrations through asyncio.run() and create_async_engine(), so asyncpg is the only PostgreSQL driver in the project. psycopg2 is deliberately absent rather than carried as a second dependency.
The DATABASE_URL is a computed field assembled from separate components with quote_plus encoding, so special characters in credentials cannot corrupt the connection string.
- Lines, platform layer
- 11,700
- Across 116 files
- API endpoint modules
- 6
- Pydantic schema modules
- 7
- Commits
- 3
- Plus repo initialisation
03How it’s built
Four things I actually do
Not values. Habits, each one pointing at the commit where it was practised.
- 01backend/requirements.txt(opens on GitHub in a new tab)
A decision that isn't written down didn't happen
Complexity bounds live in the function header that implements them. Every production dependency carries a line explaining why it is there and why the alternative was rejected. Six months later the reasoning is still in the repository rather than in someone's memory.
- 02backend/app/core/config.py(opens on GitHub in a new tab)
Make the failure impossible, not unlikely
Running with debug enabled in production is not a mistake to be careful about — it is a state the configuration layer refuses to construct. The validator raises at import time, so the server cannot reach the point of accepting a request in a dangerous configuration.
- 03backend/engine/banker.go:L15–L30(opens on GitHub in a new tab)
Hold the lock for as short as you can
The safety check needs a consistent view of the allocation matrices, not exclusive access for the duration of the search. So it copies them under the mutex, releases, and searches the snapshot. The critical section is a handful of copies; the O(P²·R) work happens outside it.
- 04backend/app/main.py(opens on GitHub in a new tab)
A system you cannot observe is a system you cannot operate
Every request carries a UUID bound into the logging context, so a single trace ID connects middleware, route handler, service and query. On the interface side the same instinct produces explicit loading, empty and error states rather than a spinner that means nothing.
04Stack
Split by whetherI have shipped it
Everything in the first tier points at a repository. Everything in the second is honest about being study rather than delivery.
Shipped in production
Used to build something that runs, and pointed at below.
- Go
- deadlockd — concurrency engine, WebSocket hub
- Python
- VAYU-DRISHTI — FastAPI backend, services
- TypeScript
- deadlockd — typed socket client
- FastAPI
- App factory, versioned router, 6 endpoint modules
- PostgreSQL · PostGIS
- Async SQLAlchemy 2.0, GeoAlchemy2
- SQLAlchemy · Alembic
- Async engine, PostGIS migrations
- Pydantic v2
- Settings, validation, 7 schema modules
- Next.js · React
- deadlockd client, React Flow graph
- Tailwind CSS
- deadlockd interface
- Docker · Compose
- Both projects, with entrypoints
- GitHub Actions
- Test and build gates on both repos
- structlog
- JSON logging, request-ID tracing
- pytest · go test
- Behavioural tests in both projects
- Streamlit · Folium
- VAYU-DRISHTI dashboard and GIS map
Working knowledge
Used in coursework and study, not yet in anything I have shipped publicly.
- C · C++
- Data structures, algorithms, systems coursework
- scikit-learn
- Classification and evaluation workflows
- Pandas · NumPy
- Data processing and analysis
- Redis
- Caching and queueing patterns
- Linux
- Daily driver, shell tooling, deployment
05Engineering record
What is actuallyin the repositories
Not stars or streaks. Whether there are tests, whether CI runs them, and whether the thing deploys.
| Project | Tests | CI | Container | Deploy |
|---|---|---|---|---|
| deadlockd | Go behavioural suite | go mod verify · go test · frontend build | Dockerfile + compose | Live — deadlockd.vercel.app |
| VAYU-DRISHTI | pytest + fixtures | Feature branches, PR review | Dockerfile + compose + entrypoint | Local / staging |
06Now
What I’m looking for
Backend and systems work where correctness matters more than surface area.
Currently finishing a B.Tech in Computer Science and Engineering at Lovely Professional University, and extending VAYU-DRISHTI’s GIS layer from interface contracts to real raster tiles.
If you are building something where the hard part is underneath — concurrency, data layers, observability, the platform other people build on — I would like to hear about it.
- GitHub
- github.com/slazyverse ↗
- linkedin.com/in/slazyverse ↗