Skip to main content

Observability, Performance, and Deployment

Watch First

Why This Matters

Production Rust services must be operated, debugged, and improved. A fast binary is not enough if the team cannot tell what failed, why it failed, how often it fails, or how to roll it back.

Performance work should start with measurement, not folklore.

What You Will Build

Prepare the service for deployment with tracing, health/readiness routes, a Dockerfile, CI checks, and a short operations guide.

Concept

Operational readiness has several paths:

Use logs for events, traces for flow, metrics for trends, and health/readiness checks for orchestration.

Rust Pattern

Use structured fields:

#[tracing::instrument(skip(service), fields(task_id = %task_id))]
pub async fn complete_task(
service: &TaskService,
task_id: TaskId,
) -> Result<Task, TaskError> {
let task = service.complete(task_id).await?;
tracing::info!(status = ?task.status, "task completed");
Ok(task)
}

The log should help answer what happened without parsing a sentence.

Practice

Keep this mistake out of your first implementation.

Do not add vague logs everywhere:

println!("here");
println!("done");

Useful logs have fields, categories, and correlation IDs.

Keep these concrete mistakes out of your work.

  • Adding logs without useful fields.
  • Optimizing allocations before measuring a bottleneck.
  • Ignoring readiness and migration state.
  • Creating Dockerfiles that are large or leak build secrets.
  • Running integration tests only locally, not in CI.

Use this sequence. Do not move to the next row until you have produced the artifact in the right column.

StepFocusArtifact
Structured loggingFields, request IDs, resource IDs, error categoriesLogging setup
TracingSpans around requests, DB calls, jobs, external callsTrace instrumentation
Health and readiness/health, /ready, DB connectivity, migration statusHealth routes
MetricsRequest counts, latency, queue depth, job outcomesMetrics plan
Performance mindsetMeasure first, optimize bottleneckProfiling note
Rust performance basicsAllocation, iterators, hot paths, backpressureSmall optimization exercise
Database performanceIndexes, N+1, pool sizing, paginationQuery review
ContainerizationRelease binaries, small runtime image, env configDockerfile
CI/CDfmt, clippy, test, audit, image build, integration checksCI workflow

Build this now. Keep each change small enough that you can run cargo check, cargo test, and inspect the diff.

Add:

  • request tracing middleware,
  • /health and /ready,
  • structured error logs,
  • a Dockerfile,
  • a CI workflow that runs formatting, linting, tests, and a dependency audit,
  • an operations guide with startup, config, migration, and rollback notes.

After your own attempt, use another reviewer or an AI tool as a second pass. Accept a suggestion only when you can explain why it preserves the lesson design.

Ask AI to containerize the service. Review whether:

  • it builds in release mode,
  • it separates build and runtime stages,
  • it avoids copying secrets,
  • it handles config through environment,
  • it documents how migrations run.

You can move on when these statements are true.

  • Can operators tell whether the service is healthy?
  • Are request IDs or trace IDs available?
  • Are logs structured and safe?
  • Are metrics tied to user-visible or operational outcomes?
  • Was performance measured before optimization?
  • Can the service be built and deployed from CI?

Curated Resources

Next Step

Continue to Beyond Backend.