Skip to content

Middleware and metric to track per-database HTTP response egress - #5611

Open
gefjon wants to merge 8 commits into
masterfrom
phoebe/http-egress-middleware
Open

Middleware and metric to track per-database HTTP response egress#5611
gefjon wants to merge 8 commits into
masterfrom
phoebe/http-egress-middleware

Conversation

@gefjon

@gefjon gefjon commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Description of Changes

This commit adds a new Prometheus metric, spacetime_http_response_size_bytes_total, which tracks bytes sent as responses to HTTP requests related to the database. This includes the sql and call routes, guest-defined HTTP handlers, logs, plus some misc. management routes. Notably, the subscribe route, which initiates a long-lived WebSocket connection, is not counted by the new metric, as we already track its egress separately.

The new metric is tracked by an Axum middleware.

API and ABI breaking changes

N/a

Expected complexity level and risk

1 or 2? I don't have a huge amount of confidence any time I touch our Axum stuff, but this is just metrics, and (at least currently) not billed metrics.

Testing

  • New unit tests which assert that the middleware functions correctly when used with a mocked router.
  • I don't know how to integration-test metrics.

This commit adds a new Prometheus metric,
`spacetime_http_response_size_bytes_total`,
which tracks bytes sent as responses to HTTP requests related to the database.
This includes the `sql` and `call` routes, guest-defined HTTP handlers,
logs, plus some misc. management routes.
Notably, the `subscribe` route, which initiates a long-lived WebSocket connection,
is not counted by the new metric, as we already track its egress separately.

The new metric is tracked by an Axum middleware.
@gefjon
gefjon requested a review from joshua-spacetime July 28, 2026 21:28
@gefjon gefjon added the release-any Can land in any release window. Will not block a release deployment. label Jul 28, 2026

@joshua-spacetime joshua-spacetime left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. I just have one billing related question.

Also can you open a PR to incorporate this metric into billing? Even if you'd like to collect some data before flipping the switch.

Comment thread crates/client-api/src/routes/database.rs Outdated
Comment thread crates/core/src/host/host_controller.rs Outdated
Comment thread crates/core/src/host/host_controller.rs

@joshua-spacetime joshua-spacetime left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. I already reviewed and approved #5681. So feel free to include it in this change and merge them both together.

gefjon and others added 3 commits August 6, 2026 16:53
Based on and targeting #5611 . I thought this was a significant enough
change to be worth reviewing separately.

# Description of Changes

The middleware responsible for the metric
`spacetime_http_response_size_bytes_total` has to resolve a request's
`:name_or_identity` from name to identity in order to compute the
correct metrics label, and from identity to referent database in order
to avoid allocating metrics labels for non-existent databases in
response to ill-formed requests.

Prior to this commit, the middleware did said resolution, then discarded
the results, and the specific route handlers did the same resolution
again. With this commit, the middleware is expanded to be fully
responsible for database resolution. It attaches the resolved `Database`
record to the request as an extension, and the route handlers read that
extension rather than reading and resolving the `:name_or_identity`
themselves.

A small number of routes have behavior on non-existent databases other
than returning 404. These 404s may occur either when a name is not bound
to an identity, or when an identity is not bound to a database. (N.b. a
name may be bound to an identity without that identity being bound to a
database, which is a somewhat silly situation.) Rather than increasing
the complexity of the middleware to cope with these behaviors or
changing the behavior of these routes by applying the middleware to
them, we opt to simply exclude these routes from the middleware,
applying it only to routes which want the 404 response behavior.

The specific routes exluded from the middleware are:
- `PUT /database/:name_or_identity`, which creates a new database if the
name is not already in use.
- `DELETE /database/:name_or_identity`, which is a no-op on a
non-existent database.
- `/database/:name_or_identity/identity`, which only resolves a name to
an identity, and does not check whether that identity refers to a
database.
- `GET /database/:name_or_identity/subscribe`, already excluded prior to
this commit, whose response egress is tracked by a different metric than
the one used by this middleware.

All of the newly excluded routes are infrequent operations with small
responses, and said responses are not user-controlled, so it's probably
fine that they don't get counted by the egress metric.

# API and ABI breaking changes

N/a

# Expected complexity level and risk

<!--
How complicated do you think these changes are? Grade on a scale from 1
to 5,
where 1 is a trivial change, and 5 is a deep-reaching and complex
change.

This complexity rating applies not only to the complexity apparent in
the diff,
but also to its interactions with existing and future code.

If you answered more than a 2, explain what is complex about the PR,
and what other components it interacts with in potentially concerning
ways. -->

# Testing

- [x] New automated tests that affected routes don't re-resolve names
unnecessarily.
- [x] Other behavior should be covered by existing tests.
See comments in mcp.rs
@gefjon
gefjon disabled auto-merge August 7, 2026 17:17
@gefjon
gefjon enabled auto-merge August 7, 2026 17:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release-any Can land in any release window. Will not block a release deployment.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants