NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #1061 most downloaded on PyPI
Instrument your FastAPI app with Prometheus metrics
Last release 2 months ago
26 Jul 2026
Release timing varies
gaps range from 9 days to 1.2 years
Nearly every release is documented
notes for 40 of 41 stable releases
1 version withdrawn
withdrawn after publishing
6 years old
45 releases · first in 2020
Added new optional parameter should_include_root_path to the Instrumentator constructor. When set to True, the default exported Prometheus metrics wil
should_include_root_path to the Instrumentator constructor. When set to True, the default exported Prometheus metrics will include the FastAPI app's effective root_path in the handler label. Defaults to False to maintain backwards compatibility. Requested in #390 and implemented in #391.One column per quarter.
Nothing published for this version
Nothing published for this version
Nothing published for this version
Replaced deprecated asyncio.iscoroutinefunction() with inspect.iscoroutinefunction() in Instrumentator.add() to avoid warnings on Python 3.12+ in #378…
asyncio.iscoroutinefunction() with inspect.iscoroutinefunction() in Instrumentator.add() to avoid warnings on Python 3.12+ in #378.Fixed resolving route names for routers registered via include_router() on FastAPI 0.116+ leading to AttributeError getting raised on every request. T
include_router() on FastAPI 0.116+ leading to AttributeError getting raised on every request. The internal route name resolution now also handles _IncludedRouter and recurses into the included router's own routes so the Prometheus label reflects the leaf endpoint. Thanks to @adeebmirza in #371 for fixing it.BREAKING: Ported project to Starlette v1. This includes new required minimum versions of Python, Starlette, and FastAPI. Bumped starlette dependency f
starlette dependency from >=0.30.0,<1.0.0 to >=1.0.0,<2.0.0. Bumped requires-python from >=3.8 to >=3.10 (starlette dropped support). Bumped fastapi dev dependency to ^0.133.0 (first version supporting starlette v1). Adjusted middleware app parameter type from Starlette to ASGIApp. Thanks to @bgermann in #357 for implementing it.starlette dependency
from >=0.30.0,<1.0.0 to >=1.0.0,<2.0.0. Bumped requires-python from
>=3.8 to >=3.10 (starlette dropped support). Bumped fastapi dev
dependency to ^0.133.0 (first version supporting starlette v1). Adjusted
middleware app parameter type from Starlette to ASGIApp. Thanks to
@bgermann in
#357
for implementing it.Included metrics closure creators have new optional parameter custom_labels to set additional custom static labels. Parameter has not been added to th
custom_labels to set additional custom static labels. Parameter has not been added to the Instrumentator() constructor. Thanks to @iocentos for requesting this in #279 and @martian711 in #287 as well as @Budlee in #326 for implementing it.These release notes also cover 7.0.1 which has been yanked due to incorrect license identifier on PyPI.
Migrated `pyproject.toml` to support PEP 621. This comes with a migration to Poetry 2.0. Thanks to @alexted bringing this up in #323.
Major release with a single breaking change: Python 3.7 is not supported anymore. Beyond that, three improvements based on various pull requests.
Major release with a single breaking change: Python 3.7 is not supported anymore. Beyond that, three improvements based on various pull requests.
Instrumentator now works without FastAPI. This is possible because every FastAPI app is also a Starlette app (but not the other way around). Or to be more specific: FastAPI uses Starlette for things like routing and middleware this package relies on. The change is backwards compatible, even type checkers like mypy should continue working. Thanks to @mvanderlee for proposing this in #280 and implementing it in #288.
Middleware also records duration without streaming in addition to the already existing total latency (i.e. the time consumed for streaming is not included in the duration value). The differentiation can be valuable as it shows the time to first byte.
This mode is opt-in and can be enabled / used in several ways: The Instrumentator() constructor, the metrics.default() closure, and the metrics.latency() closure now come with the flag should_exclude_streaming_duration. The attribute modified_duration_without_streaming has been added to the metrics.Info class. Instances of metrics.Info are passed to instrumentation functions, where the added value can be used to set metrics.
Thanks to @dosuken123 for proposing this in #291 and implementing it in #290.
Relaxed type of get_route_name() argument to HTTPConnection. This allows developers to use the get_route_name function for getting the name of websocket routes as well. Thanks to @pajowu for proposing and implementing this feature in #276.
Added label method to metric http_request_duration_seconds from default metrics. Thanks to @alcidesmig for implementing this in #251.
method to metric http_request_duration_seconds from default metrics. Thanks to @alcidesmig for implementing this in #251.Small release with a small breaking change leading to a big version change following semantic versioning.
Small release with a small breaking change leading to a big version change following semantic versioning.
Breaking change only affects users that have custom instrumentations that access info.response.body, a feature introduced with 5.10.0 few weeks ago. See below for more information.
BREAKING: Disabled passing response body to instrumentation functions. Moved behind whitelist that is empty by default. Changes a feature introduced with 5.10.0. Only affects users that have custom instrumentations that access info.response.body.
Opt-in via new parameter body_handlers added to instrumentator constructor. Parameter takes list of pattern strings to match handlers. For old behavior, pass argument [r".*"] to match all handlers:
instrumentator = Instrumentator(body_handlers=[r".*"])
Motivation for change: Collecting body negatively impacts performance of responses with largish body.
Thanks to @bbeattie-phxlabs for raising this issue in #234 and implementing it in #233 / #238.
Small release with a small breaking change leading to an increase of the major version according to semantic versioning.
Breaking change only affects users that have custom instrumentations that access
info.response.body, a feature introduced with 5.10.0 few
weeks ago. See below for more information.
Ask or discuss anything quick about the release in the discussion #239.
BREAKING: Disabled passing response body to instrumentation functions.
Moved behind whitelist that is empty by default. Changes a feature introduced
with 5.10.0. Only affects users that have custom
instrumentations that access info.response.body.
Opt-in via new parameter body_handlers added to instrumentator constructor.
Parameter takes list of pattern strings to match handlers. For old behavior,
pass argument [r".*"] to match all handlers:
instrumentator = Instrumentator(body_handlers=[r".*"])
Motivation for change: Collecting body negatively impacts performance of responses with largish body.
Thanks to @bbeattie-phxlabs for raising this issue in #234 and implementing it in #233 / #238.
Fixed info.response.body in instrumentation functions being wrongfully empty if response is not streamed. Affects a feature that was introduced with r
Improved typing hints and enabled stricter rules for MyPy. Thanks to @tomtom103 for implementing this in #231.
…as arguments instead of a single one. Non-breaking change. Implemented in pull request #230.
Minor release containing several fixes and a small enhancement. Fixes are related to multi process mode, a regression introduced with the previous release, and errors that started to occur with current versions of Starlette and FastAPI.
Ask or discuss anything quick about the release in the discussion #221.
add() method to accept an arbitrary number of instrumentation functions as arguments instead of a single one. Non-breaking change. Implemented in pull request #230.Fixed multi process mode in expose() method that handles the /metrics endpoint. Due to reusing the registry assigned to the instrumentator it could lead to duplicated metrics. Now the endpoint follows recommendation from Prometheus client library documentation. Also improved multi process unit tests. Closed issue #228 and #227. Fixed in pull request #229.
Fixed NameError and "Duplicated timeseries..." errors that started to occur with latest versions of Starlette / FastAPI in combination with multiple middlewares. Instrumentation closures are now optional and the instrumentator handles this accordingly. Thanks to @alexted and others for reporting errors. Thanks to @frankie567 for pointing out the change in Starlette. Related to pull request #153 and issue #214. Closed issue #219. Done in pull request #220.
Added missing registry parameter to remaining metrics functions. This enables passing custom registry to other metrics functions than default. Related to pull request #153. Closed issue #219. Done in pull request #220.
Notable changes that might have an impact on existing setups is the automatic instrumentation of mounted apps and the deprecation of the lowercase pro…
First release in several months. Includes new features and fixes from various contributors. Notable changes that might have an impact on existing setups is the automatic instrumentation of mounted apps and the deprecation of the lowercase prometheus_multiproc_dir environment variable.
Ask or discuss anything quick about the release in the discussion #221.
Added smart handling of mounted apps. Previously the URL handler logic did not handle mounted apps and always returned just the prefix in that case. Based on code from elastic/apm-agent-python licensed under the permissive BSD-3-Clause License. Thanks to @LordGaav for proposing this enhancement / fix and implementing it in #208. Related to issues #31 and #121.
Added optional parameters metric_namespace and metric_subsystem to instrument() method to configure namespace and subsystem for all metric names. Check the README.md for more information. Thanks to @phbernardes for proposing this enhancement and implementing it in #193.
Added passthrough of body to info.response. This enables metrics that work based on data in the body. Thanks to everyone who brought this up in #76 and to @HadilD for implementing it in #203.
Allowed passing a custom registry to be used instead of using the default one. This would be useful in particular when testing multiple FastAPI apps (e.g. microservices) in the same tests run. Note that there are issues with the current implementation in certain corner cases. Thanks to @tiangolo for for proposing this enhancement and implementing it in #153.
Environment variable used by should_respect_env_var (default ENABLE_METRICS) now accepts truthy values like 1 and true and not just True. Thanks to @chbndrhnns for proposing this enhancement in #27 and implementing it in #28.
Added support for asynchronous instrumentation functions. The add() method now accepts them in addition to "normal" functions and the instrumentator middleware will await them appropriately. Thanks to @AndreasPB for for proposing this enhancement and implementing it in #61. Thanks to @Skeen for contributing to the discussion.
Fixed status code in metric being "Hxx" when http.HTTPStatus enumeration is used in combination with grouping of status codes. Thanks to @Leem0sh and others for raising the issue in #190. Thanks to @nikstuckenbrock and @blag for fixing it in #192.
Fixed documentation in main README on how to use prometheus-fastapi-instrumentator with current versions of FastAPI. Related to issues #214 and #80. Thanks to @alfaro28 and @harochau.
prometheus_multiproc_dir and replaced it with PROMETHEUS_MULTIPROC_DIR. This matches the behavior of the Prometheus Python client library. This fixes #89 and #50. Thanks to all the people who brought this up. Thanks to @michaelusner for implementing the deprecation in #42 / #217.No bug fixes or new features. Just an important improvement of the documentation.
No bug fixes or new features. Just an important improvement of the documentation.
@app.on_event("startup") to prevent crashes on startup. Thanks to @mdczaplicki and others.@app.on_event("startup") to prevent crashes on
startup in certain situations. Done in
#168.
Thanks to @mdczaplicki and others.This release fixes a small but annoying bug. Beyond that the release includes small internal improvements and bigger changes to CI/CD.
This release fixes a small but annoying bug. Beyond that the release includes small internal improvements and bigger changes to CI/CD.
py.typed file to package to improve typing annotations (#137). Thanks to @mmaslowskicc for proposing and implementing this.py.typed file to package to improve typing annotations. Done in
#137.
Thanks to @mmaslowskicc for proposing and
implementing this.None instead of an empty list. Done in
#155.
Thanks to @yezz123.Refactored the middleware to an ASGI implementation. Thanks to @Kludex and @adriangb. #139.
Refactored the middleware to an ASGI implementation. Thanks to @Kludex and @adriangb. #139.
deps: regression too strict version requirements #136 (36bc045). Thanks to @graipher for raising the issue.
Removed support for Python 3.6 and overall cleanup
Updated prometheus-client dependency version constraint ^0.8.0 that only allows versions in the range [0.8.0, 0.9.0[. This is not correct and leads to
prometheus-client dependency version constraint ^0.8.0 that only
allows versions in the range [0.8.0, 0.9.0[. This is not correct and leads
to conflicts when you want to install the newest prometheus client library
version and this package. Switched to explicit contraints to ensure this does
not happen again.Nothing published for this version
Added parameter tags to method expose(). Passthrough to FastAPI to support tagging. Related to #17. Thanks to @chisaipete for proposing this enhanceme
tags to method expose(). Passthrough to FastAPI to support
tagging. Related to
#17.
Thanks to @chisaipete for proposing this
enhancement.Fixed error "Duplicate mime type charset=utf-8 on Response Header". Done by changing the way the content type header is set. Seems like when Starlette
media_type parameter is used to provide content type, the charset is
appended again automatically even if it already is part of Content-Type.
Thanks to @flobaader for raising this issue in
#16.Added new metrics closure requests. Thanks to @jpslopes for proposing this enhancement in #15.
Fixed dependency regression introduced in 5.4.0 by pinning FastAPI dependency to fastapi = "0.38.1, <=1.0.0" instead of fastapi = ">=0.38.1, <=1.0.0".
fastapi = "0.38.1, <=1.0.0" instead of fastapi = ">=0.38.1, <=1.0.0".
Thanks to @PaulFlanaganGenscape for
raising this issue in
#14.Added new metric that monitors the number of requests in progress. Can be configured to have the labels handler and method. It can be activated with s
handler and method. It can be activated with
should_instrument_requests_inprogress and configured with inprogress_name
and inprogress_labels.Fixed expose method in the instrumentator ignoring the endpoint argument and always creating the endpoint with on the /metrics path. Variable was miss
expose method in the instrumentator ignoring the endpoint argument
and always creating the endpoint with on the /metrics path. Variable was
missing. Thanks to @funkybase for raising this
issue in
#9.Added parameter should_gzip to expose method. It will check for gzip in the Accepted-Encoding header and gzip the metrics data. You can expect a reduc
should_gzip to expose method. It will check for gzip in
the Accepted-Encoding header and gzip the metrics data. You can expect a
reduction of around 90 % in bytes.### Changed - Improved README.md.
README.md.### Changed - Improved README.md.
README.md.Fixed lack of error wrapping of a runtime error is raised inside the endpoint. In addition this instrumentator assumed that info.response will always
info.response will always
contain the headers attribute which is not the case if a runtime error is
thrown. Now the metrics check if the response is None and that the headers
attribute actually exists. Tests have been added as well. Thanks to
@stepf for raising this issue in
#7.response_size and combined_size no longer skip
if content length is not found. Now the content length will default no zero
bytes.Added parameter should_only_respect_2xx_for_highr to default metrics. Allows you to only put successful requests into the high resolution bucket.
should_only_respect_2xx_for_highr to default metrics.
Allows you to only put successful requests into the high resolution bucket.Added parameters to set namespace and subsystem to all available metrics.
Added labels handler, status, method to http_requests_total in default.
handler, status, method to http_requests_total in
default.handler to http_request_size_bytes.handler to http_response_size_bytes.full to default.http_in_bytes_total to http_request_size_bytes.http_out_bytes_total to http_response_size_bytes.http_highr_request_duration_seconds to
http_request_duration_highr_seconds.http_lowr_request_duration_seconds to
http_request_duration_seconds.http_request_size_bytes and http_response_size_bytes
into summaries.method and status from
http_request_duration_seconds.BREAKING: Switched the default fast track metric to a more advanced one.
A lot of breaking changes in this release. Prometheus FastAPI Instrumentator is now more modular than before and there are multiple different metrics…
A lot of breaking changes in this release. Prometheus FastAPI Instrumentator is now more modular than before and there are multiple different metrics one can choose from out of the box or add custom metrics that will be automatically applied to the FastAPI.
If you just use the default instrumentator without setting any parameters, nothing changes. The defaults stay the same.
If you use any of the paramters that were available in the Instrumentator
constructor you have to check if they are still available or not. Some of them
have been moved to the corresponding metric closure / function.
/metrics is not excluded by default anymore.Fixed wrong var name in README.md.
README.md.Added option to exclude optional /metrics endpoint from schema.
/metrics endpoint from schema.should_respect_env_var_existence to
should_respect_env_var.should_respect_env_var is True, the respective env var
must be true and not just any random value.should_respect_env_var from
PROMETHEUS to ENABLE_METRICS.Added option should_respect_env_var_existence. This makes it possible to only instrument and expose your FastAPI if a given environment variable is se
should_respect_env_var_existence. This makes it possible to
only instrument and expose your FastAPI if a given environment variable is
set. Use case: A base FastAPI app that is used by multiple distinct apps. The
apps only have to set the variable to be instrumented. Deactivated by default
and the default env var is PROMETHEUS.The observed latency values can now be rounded to a certain number of decimals as an opt-in feature. This can improve bytes per sample required in sto
Nothing. Dummy release.
Nothing. Dummy release.
Renamed project from _Prometheus FastAPI Exporter_ to _Prometheus FastAPI Instrumentator_. Reasoning behind this change: Focus of this project is the
Your coding agent can read these notes before it upgrades. Set up the MCP server →