Skip to content

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

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

Middleware and metric to track per-database HTTP response egress#5611
gefjon wants to merge 2 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
Contributor

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 on lines +1696 to +1699
let Ok(Ok(database_identity)) = name_or_identity.try_resolve(&worker_ctx).await else {
// The provided name doesn't map to an `Identity`.
// Run the route unchanged (as opposed to returning an error from the middleware)
// to preserve the error-handling behavior of the route.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should we pass the resolved identity along so that the route doesn't try to resolve it again?


// Remove all gauges associated with a database.
// This is useful if a database is being deleted.
/// Removes metrics associated with a database when the database is deleted.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The new comment is misleading. These metrics are not removed only when a database is deleted. They are removed on HostController::exit_module_host.

Comment on lines +1583 to +1584
/// Despite the historical function name, this cleans up per-database metric
/// series even when they are not literally `Gauge`s or `IntGauge`s.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Do we have billing related tests that confirm this is safe to do? A gauge reset is different than a counter reset. If handled improperly, this could result in negative billing.

And on a related note, we should probably have an alert for negative billing if we don't have one already (this is more of a note for myself).

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