What does django-silk record through SilkyMiddleware and silk_profile, and when is it a better fit than django-debug-toolbar?
answer
- records to the database
- its own UI under /silk/
- a block, not a page
- APIs without HTML
basics
~20 sdjango-silk's SilkyMiddleware saves each request, its SQL queries and timings to database tables and shows them at /silk/; silk_profile records a named block's time and queries. It suits JSON APIs and after-the-fact comparison, where no HTML page exists.
solid answer
~40 sdjango-silk is installed as the `silk` app with `silk.middleware.SilkyMiddleware`, its URLs at `path("silk/", include("silk.urls", namespace="silk"))`, and `migrate`, because it **stores** what it records in database tables. For every intercepted request it saves the path, method, status, headers, bodies, timings and each SQL query with its time and stack trace, and its UI lists and sorts them, and can generate a `curl` command or Python code to replay a request. `silk_profile` from `silk.profiling.profiler` works as a decorator or a context manager (which requires a `name`) and records the time and queries inside that block. `SILKY_PYTHON_PROFILER = True` adds a cProfile run per request. It fits better than the toolbar for JSON APIs called by other clients, and for comparing many requests later rather than inspecting one page live.
code
python · 13 linesfrom django.http import JsonResponse
from silk.profiling.profiler import silk_profile
from .models import Cart
from .pricing import price_cart # the project's own pricing code
@silk_profile(name="Checkout quote API")
def checkout_quote(request, cart_id):
cart = Cart.objects.get(pk=cart_id, owner=request.user)
with silk_profile(name=f"Price cart #{cart.pk}"):
quote = price_cart(cart)
return JsonResponse({"total": str(quote.total)})go deeper
Know that django-silk records requests and their SQL on the server and shows them at /silk/, which helps with API endpoints.
Explain the install steps including migrate, what the middleware stores, and the two forms of silk_profile and their naming rule.
Control silk's cost and exposure: sampling, ignored paths, recorded-request caps, and where its stored bodies and queries end up.
Decide which profiling tools the team standardises on for pages and APIs, and where continuous production profiling needs a different kind of tool.
## What django-silk is **django-silk** is a third-party profiling and inspection app for Django. Where django-debug-toolbar draws a panel on the HTML page you are looking at, silk **records** requests on the server and lets you browse them afterwards in its own interface. That difference in design decides when to use which. ## Installing it 1. `pip install django-silk`. 2. Add `"silk"` to `INSTALLED_APPS`. 3. Add `"silk.middleware.SilkyMiddleware"` to `MIDDLEWARE`. If you use `GZipMiddleware`, list it **before** silk's middleware, or silk hits an encoding error; and any middleware listed before silk that returns early stops silk from seeing the request. 4. Add `path("silk/", include("silk.urls", namespace="silk"))` to the URLconf. 5. Run `python manage.py migrate`: silk keeps its data in its own tables. ## What `SilkyMiddleware` records For each request it intercepts, silk saves: - method, path, status code, timing and the number of queries; - request and response headers and bodies (cookies and the `Authorization` header masked by default); - every SQL query with its time, the tables it touched and a stack trace to the calling code. The UI at `/silk/` summarises the slowest and most query-heavy requests, lets you sort and filter, and for each request can generate a `curl` command and Python test-client code to replay it. Which requests are recorded is configurable: `SILKY_INTERCEPT_PERCENT` (default `100`) samples a share of them, `SILKY_INTERCEPT_FUNC` decides per request, and `SILKY_IGNORE_PATHS` skips paths such as health checks. `SILKY_MAX_RECORDED_REQUESTS` (default `10**4`) caps the stored history, trimmed on a share of requests. ## `silk_profile`: timing a block Import it from `silk.profiling.profiler`. It has two forms: | Form | Name | Typical use | |---|---|---| | decorator, `@silk_profile(name="...")` | optional; defaults to the function's name | a view, a method or a service function | | context manager, `with silk_profile(name="..."):` | **required**, or it raises `ValueError` | a block inside a function, with a dynamic name such as the order ID | Each profile records the block's start and end time and the SQL queries run inside it, attached to the current request in the UI. It only records when silk's app and middleware are installed and a request is being recorded; otherwise it logs a warning and runs the code untouched. `SILKY_DYNAMIC_PROFILING` applies the same decorator at runtime to functions you cannot edit, such as a library's. ## Whole-request profiling `SILKY_PYTHON_PROFILER = True` runs Python's `cProfile` for each recorded request and shows the result on the request's profiling page. Silk's docs note that from Python 3.12 `cProfile` cannot run concurrently, so silk will not profile a request while another profile is running. ## Silk or the toolbar? | Need | Better tool | |---|---| | Look at one HTML page's SQL, templates, cache and signals while developing | django-debug-toolbar | | Inspect a JSON API called by a mobile app, a single-page frontend or another service | django-silk | | Compare many requests over time, sort by slowest | django-silk | | Time one block inside a view with its own queries | django-silk's `silk_profile` | | No database writes or migrations for the tool | django-debug-toolbar (its default store is in memory) | Many teams run both in development: the toolbar for pages, silk for APIs. Silk's recording writes to the database on every intercepted request, so it adds overhead to the requests it measures. ## Reading a silk recording A typical workflow on an API: call the endpoint a few times from the client, open `/silk/`, sort requests by time or by query count, open the slowest, then read its SQL tab (sorted by time, with the tables involved and the calling stack) and any `silk_profile` blocks attached to it. Because recordings persist, you can change the code, call the endpoint again and compare the two entries side by side, which a per-page toolbar cannot do once you have navigated away.
- Why does django-silk need migrate while django-debug-toolbar usually does not?Silk persists every recorded request, query and profile in its own database tables so you can browse them later, which needs its migrations applied. The debug toolbar keeps results for recent requests in memory by default (`TOOLBAR_STORE_CLASS` is a memory store holding `RESULTS_CACHE_SIZE`, 25, requests); it offers a database store as an option, not a requirement.
saying these in an interview costs you the question
- django-silk injects a panel into each HTML page
- silk_profile works without silk's middleware installed
- django-silk keeps its data in memory only
- silk_profile as a context manager can be used without a name
- django-silk turns cProfile on for every request by default