How do I log asynchronous thinsinatrarack requests?
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
In a Thin plus Sinatra plus Rack stack, request logging can become part of the hot path if every request waits for file I/O. Asynchronous logging moves the actual write to a background worker so the Rack request thread only enqueues a log event and continues.
That idea is simple, but a good implementation still needs structure. You need one shared queue, one long-lived writer, clean shutdown, and enough metadata in each event to make the logs useful later.
Log From Middleware, Not From Every Route
Request logging is most consistent when it happens in Rack middleware. That gives you one place to capture request method, path, status code, and timing for every endpoint.
A minimal Sinatra app might look like this:
The middleware layer is where you should measure and emit request logs rather than scattering logging calls across route blocks.
Build a Queue-Based Async Logger
The usual pattern is a Queue plus one worker thread:
This keeps disk writes off the request path. Each request only pushes a Ruby hash into the queue.
Capture Request Details in Middleware
Now wrap the app with middleware that records request metadata and duration:
This produces one structured event per request and keeps the logging concern out of application routes.
Wire It Up in Rack
Mount the middleware in config.ru:
Then start Thin as usual:
At that point, requests are logged asynchronously through the shared worker.
Shutdown and Backpressure Matter
An async logger that never flushes on shutdown is incomplete. Trap process signals and stop the worker cleanly:
You should also think about queue growth. A completely unbounded queue can consume too much memory during traffic spikes or slow disk conditions. In production, teams often add:
- queue length metrics
- a drop policy for low-priority logs
- synchronous fallback for critical failures
Async logging is not just a code trick. It is a small subsystem with operational behavior.
Common Pitfalls
The biggest mistake is creating a new logger thread per request. That destroys the performance benefit and adds unnecessary concurrency overhead.
Another common issue is using an unbounded queue without any monitoring. If log writes slow down under load, memory growth can become the new problem.
Developers also forget graceful shutdown. Without it, the last queued events can be lost whenever the process stops.
Finally, avoid mixing multiple output formats in one file. Structured JSON lines are much easier to consume downstream than a blend of plain text and ad hoc hashes.
Summary
- In Sinatra and Rack, asynchronous logging is best implemented in middleware.
- Use one shared queue and one background writer instead of logging directly from the request path.
- Capture consistent request fields such as method, path, status, and duration.
- Handle shutdown cleanly so queued log entries are flushed.
- Treat queue growth and logger failure as operational concerns, not just implementation details.
Related reading
- How do I log trace id in Java Spring Async thread
- How do I make cloud-init startup scripts run every time my EC2 instance boots?
- How do I monitor clipboard content changes in C?
- How do I monitor the computer''s CPU, memory, and disk usage in Java?
- How do I make a large number of concurrent HTTPS requests robustly in Clojure /Java
- How do I make multiple async calls, then execute a function after all calls have completed?
- How do I pass environment variables to Docker containers?
- How do I pass environment variables to Docker containers?

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.