Skip to content

Telemetry

Tuist provides three complementary observability signals: metrics (Prometheus), traces (OpenTelemetry), and logs (Loki-compatible). All three are optional and can be enabled independently.

Distributed tracing (OpenTelemetry)#

Tuist supports OpenTelemetry for distributed tracing. When enabled, the server emits traces for HTTP requests (Phoenix and Bandit), database queries (Ecto), outgoing HTTP calls (Finch), and Broadway message processing. These traces let you understand request latency, identify slow queries, and follow requests across services.

Configuration#

Set the following environment variable to enable trace export:

Environment variable Description Required Default Example
TUIST_OTEL_EXPORTER_OTLP_ENDPOINT The gRPC endpoint of an OpenTelemetry Collector (e.g. Grafana Alloy, Jaeger, or any OTLP-compatible collector) No http://localhost:4317

When this variable is not set, tracing is disabled and adds no overhead.

Instrumented libraries#

The following libraries are automatically instrumented when tracing is enabled:

  • Bandit -- HTTP server connection spans
  • Phoenix -- Request lifecycle spans (controller actions, LiveView)
  • Ecto -- Database query spans with query metadata
  • Finch -- Outgoing HTTP client request spans
  • Broadway -- Message processing pipeline spans

Example setup with Grafana Alloy#

If you use Grafana Alloy as your collector, configure it to receive OTLP traces and forward them to your tracing backend (e.g. Grafana Cloud Tempo):

plaintext
otelcol.receiver.otlp "default" {
grpc {
endpoint = "0.0.0.0:4317"
}
output {
traces = [otelcol.exporter.otlp.your_backend.input]
}
}

Then set TUIST_OTEL_EXPORTER_OTLP_ENDPOINT to point to the Alloy instance, e.g. http://alloy:4317.

Log forwarding (Loki)#

Tuist can forward application logs to a Loki-compatible endpoint. This allows you to centralize logs alongside your metrics and traces for a complete observability picture. Logs are pushed via the Loki HTTP push API (/loki/api/v1/push) and include labels for app, env, and level.

Configuration#

Environment variable Description Required Default Example
TUIST_LOKI_URL The base URL of a Loki-compatible push API endpoint No http://localhost:3100

When this variable is not set, log forwarding is disabled.

Example setup with Grafana Alloy#

Grafana Alloy can act as a local log relay using its loki.source.api component:

plaintext
loki.source.api "default" {
http {
listen_address = "0.0.0.0"
listen_port = 3100
}
forward_to = [loki.write.your_backend.receiver]
use_incoming_timestamp = true
}
loki.write "your_backend" {
endpoint {
url = "https://your-loki-instance/loki/api/v1/push"
basic_auth {
username = "your-username"
password = "your-password"
}
}
}

Then set TUIST_LOKI_URL=http://alloy:3100.

You can also point TUIST_LOKI_URL directly at a Loki instance if it exposes the push API.

Prometheus metrics#

You can ingest metrics gathered by the Tuist server using Prometheus and a visualization tool such as Grafana to create a custom dashboard tailored to your needs. The Prometheus metrics are served via the /metrics endpoint on port 9091. The Prometheus' scrape_interval should be set as less than 10_000 seconds (we recommend 30 seconds to balance observability with metrics ingestion costs).

PostHog analytics#

Tuist integrates with PostHog for user behavior analytics and event tracking. This allows you to understand how users interact with your Tuist server, track feature usage, and gain insights into user behavior across the marketing site, dashboard, and API documentation.

Configuration#

PostHog integration is optional and can be enabled by setting the appropriate environment variables. When configured, Tuist will automatically track user events, page views, and user journeys.

Environment variable Description Required Default Example
TUIST_POSTHOG_API_KEY Your PostHog project API key No phc_fpR9c0Hs5H5VXUsupU1I0WlEq366FaZH6HJR3lRIWVR
TUIST_POSTHOG_URL The PostHog API endpoint URL No https://eu.i.posthog.com
Analytics Enablement

Analytics are only enabled when both TUIST_POSTHOG_API_KEY and TUIST_POSTHOG_URL are configured. If either variable is missing, no analytics events will be sent.

Features#

When PostHog is enabled, Tuist automatically tracks:

  • User identification: Users are identified by their unique ID and email address
  • User aliasing: Users are aliased by their account name for easier identification
  • Group analytics: Users are grouped by their selected project and organization for segmented analytics
  • Page sections: Events include super properties indicating which section of the application generated them:
    • marketing - Events from marketing pages and public content
    • dashboard - Events from the main application dashboard and authenticated areas
    • api-docs - Events from API documentation pages
  • Page views: Automatic tracking of page navigation using Phoenix LiveView
  • Custom events: Application-specific events for feature usage and user interactions

Privacy considerations#

  • For authenticated users, PostHog uses the user's unique ID as the distinct identifier and includes their email address
  • For anonymous users, PostHog uses memory-only persistence to avoid storing data locally
  • All analytics respect user privacy and follow data protection best practices
  • PostHog data is processed according to PostHog's privacy policy and your configuration

Elixir metrics#

By default we include metrics of the Elixir runtime, BEAM, Elixir, and some of the libraries we use. The following are some of the metrics you can expect to see:

We recommend checking those pages to know which metrics are available and how to use them.

Runs metrics#

A set of metrics related to Tuist Runs.

tuist_runs_total (counter)#

The total number of Tuist Runs.

Tags#

Tag Description
name The name of the tuist command that was run, such as build, test, etc.
is_ci A boolean indicating if the executor was a CI or a developer's machine.
status 0 in case of success, 1 in case of failure.

tuist_runs_duration_milliseconds (histogram)#

The total duration of each tuist run in milliseconds.

Tags#

Tag Description
name The name of the tuist command that was run, such as build, test, etc.
is_ci A boolean indicating if the executor was a CI or a developer's machine.
status 0 in case of success, 1 in case of failure.

Cache metrics#

A set of metrics related to the Tuist Cache.

tuist_cache_events_total (counter)#

The total number of binary cache events.

Tags#

Tag Description
event_type Can be either of local_hit, remote_hit, or miss.

tuist_cache_uploads_total (counter)#

The number of uploads to the binary cache.

tuist_cache_uploaded_bytes (sum)#

The number of bytes uploaded to the binary cache.

tuist_cache_downloads_total (counter)#

The number of downloads to the binary cache.

tuist_cache_downloaded_bytes (sum)#

The number of bytes downloaded from the binary cache.


Previews metrics#

A set of metrics related to the previews feature.

tuist_previews_uploads_total (sum)#

The total number of previews uploaded.

tuist_previews_downloads_total (sum)#

The total number of previews downloaded.


Storage metrics#

A set of metrics related to the storage of artifacts in a remote storage (e.g. s3).

Tip

These metrics are useful to understand the performance of the storage operations and to identify potential bottlenecks.

tuist_storage_get_object_size_size_bytes (histogram)#

The size (in bytes) of an object fetched from the remote storage.

Tags#

Tag Description
object_key The lookup key of the object in the remote storage.

tuist_storage_get_object_size_duration_miliseconds (histogram)#

The duration (in milliseconds) of fetching an object size from the remote storage.

Tags#

Tag Description
object_key The lookup key of the object in the remote storage.

tuist_storage_get_object_size_count (counter)#

The number of times an object size was fetched from the remote storage.

Tags#

Tag Description
object_key The lookup key of the object in the remote storage.

tuist_storage_delete_all_objects_duration_milliseconds (histogram)#

The duration (in milliseconds) of deleting all objects from the remote storage.

Tags#

Tag Description
project_slug The project slug of the project whose objects are being deleted.

tuist_storage_delete_all_objects_count (counter)#

The number of times all project objects were deleted from the remote storage.

Tags#

Tag Description
project_slug The project slug of the project whose objects are being deleted.

tuist_storage_multipart_start_upload_duration_milliseconds (histogram)#

The duration (in milliseconds) of starting an upload to the remote storage.

Tags#

Tag Description
object_key The lookup key of the object in the remote storage.

tuist_storage_multipart_start_upload_duration_count (counter)#

The number of times an upload was started to the remote storage.

Tags#

Tag Description
object_key The lookup key of the object in the remote storage.

tuist_storage_get_object_as_string_duration_milliseconds (histogram)#

The duration (in milliseconds) of fetching an object as a string from the remote storage.

Tags#

Tag Description
object_key The lookup key of the object in the remote storage.

tuist_storage_get_object_as_string_count (count)#

The number of times an object was fetched as a string from the remote storage.

Tags#

Tag Description
object_key The lookup key of the object in the remote storage.

tuist_storage_check_object_existence_duration_milliseconds (histogram)#

The duration (in milliseconds) of checking the existence of an object in the remote storage.

Tags#

Tag Description
object_key The lookup key of the object in the remote storage.

tuist_storage_check_object_existence_count (count)#

The number of times the existence of an object was checked in the remote storage.

Tags#

Tag Description
object_key The lookup key of the object in the remote storage.

tuist_storage_generate_download_presigned_url_duration_milliseconds (histogram)#

The duration (in milliseconds) of generating a download presigned URL for an object in the remote storage.

Tags#

Tag Description
object_key The lookup key of the object in the remote storage.

tuist_storage_generate_download_presigned_url_count (count)#

The number of times a download presigned URL was generated for an object in the remote storage.

Tags#

Tag Description
object_key The lookup key of the object in the remote storage.

tuist_storage_multipart_generate_upload_part_presigned_url_duration_milliseconds (histogram)#

The duration (in milliseconds) of generating a part upload presigned URL for an object in the remote storage.

Tags#

Tag Description
object_key The lookup key of the object in the remote storage.
part_number The part number of the object being uploaded.
upload_id The upload ID of the multipart upload.

tuist_storage_multipart_generate_upload_part_presigned_url_count (count)#

The number of times a part upload presigned URL was generated for an object in the remote storage.

Tags#

Tag Description
object_key The lookup key of the object in the remote storage.
part_number The part number of the object being uploaded.
upload_id The upload ID of the multipart upload.

tuist_storage_multipart_complete_upload_duration_milliseconds (histogram)#

The duration (in milliseconds) of completing an upload to the remote storage.

Tags#

Tag Description
object_key The lookup key of the object in the remote storage.
upload_id The upload ID of the multipart upload.

tuist_storage_multipart_complete_upload_count (count)#

The total number of times an upload was completed to the remote storage.

Tags#

Tag Description
object_key The lookup key of the object in the remote storage.
upload_id The upload ID of the multipart upload.

Authentication metrics#

A set of metrics related to authentication.

tuist_authentication_token_refresh_error_total (counter)#

The total number of token refresh errors.

Tags#

Tag Description
cli_version The version of the Tuist CLI that encountered the error.
reason The reason for the token refresh error, such as invalid_token_type or invalid_token.

Projects metrics#

A set of metrics related to the projects.

tuist_projects_total (last_value)#

The total number of projects.


Accounts metrics#

A set of metrics related to accounts (users and organizations).

tuist_accounts_organizations_total (last_value)#

The total number of organizations.

tuist_accounts_users_total (last_value)#

The total number of users.

Database metrics#

A set of metrics related to the database connection.

The repo pool metrics are sampled internally every 100ms and then exposed to Prometheus on /metrics. The last_value metrics below show the most recent pool state at scrape time. The pressure metrics further down are sums derived from those 100ms samples, which makes short saturation windows easier to spot even when they recover before the next scrape.

tuist_repo_pool_checkout_queue_length (last_value)#

The number of database queries that are sitting in a queue waiting to be assigned to a database connection.

Tags#

Tag Description
repo The repository that emitted the metric, such as postgres, clickhouse_read, or clickhouse_write.
database The backing database type, such as postgres or clickhouse.

tuist_repo_pool_ready_conn_count (last_value)#

The number of database connections that are ready to be assigned to a database query.

Tags#

Tag Description
repo The repository that emitted the metric, such as postgres, clickhouse_read, or clickhouse_write.
database The backing database type, such as postgres or clickhouse.

tuist_repo_pool_size (last_value)#

The configured number of connections in the pool.

Tags#

Tag Description
repo The repository that emitted the metric, such as postgres, clickhouse_read, or clickhouse_write.
database The backing database type, such as postgres or clickhouse.

tuist_repo_pool_checkout_queue_total_samples_sum (sum)#

The total number of repo pool polls taken (increments by 1 on every poll). Use this as the denominator when computing busyness or starvation percentages: rate(busy_samples) / rate(total_samples) or rate(starved_samples) / rate(total_samples).

Tags#

Tag Description
repo The repository that emitted the metric, such as postgres, clickhouse_read, or clickhouse_write.
database The backing database type, such as postgres or clickhouse.

tuist_repo_pool_checkout_queue_observed_sum (sum)#

The sum of queued checkout requests observed across repo pool polls. This is useful for detecting short bursts of pool contention that may not be visible in the latest queue-length sample alone.

Tags#

Tag Description
repo The repository that emitted the metric, such as postgres, clickhouse_read, or clickhouse_write.
database The backing database type, such as postgres or clickhouse.

tuist_repo_pool_checkout_queue_busy_samples_sum (sum)#

The number of repo pool polls where at least one database checkout request was waiting in the queue.

Tags#

Tag Description
repo The repository that emitted the metric, such as postgres, clickhouse_read, or clickhouse_write.
database The backing database type, such as postgres or clickhouse.

tuist_repo_pool_checkout_queue_starved_samples_sum (sum)#

The number of repo pool polls where checkout requests were queued and no ready connections were available. A sustained increase here usually means the pool is saturated.

Tags#

Tag Description
repo The repository that emitted the metric, such as postgres, clickhouse_read, or clickhouse_write.
database The backing database type, such as postgres or clickhouse.

tuist_repo_pool_db_connection_connected (counter)#

The number of connections that have been established to the database.

tuist_repo_pool_db_connection_disconnected (counter)#

The number of connections that have been disconnected from the database.

Tags#

Tag Description
tag The DBConnection listener tag that identifies the emitting repository.

HTTP metrics#

A set of metrics related to Tuist's interactions with other services via HTTP.

tuist_http_request_count (counter)#

The number of outgoing HTTP requests.

tuist_http_request_duration_nanosecond_sum (sum)#

The sum of the duration of the outgoing requests (including the time that they spent waiting to be assigned to a connection).

tuist_http_request_duration_nanosecond_bucket (distribution)#

The distribution of the duration of outgoing requests (including the time that they spent waiting to be assigned to a connection).

tuist_http_queue_count (counter)#

The number of requests that have been retrieved from the pool.

tuist_http_queue_duration_nanoseconds_sum (sum)#

The time it takes to retrieve a connection from the pool.

tuist_http_queue_idle_time_nanoseconds_sum (sum)#

The time a connection has been idle waiting to be retrieved.

tuist_http_queue_duration_nanoseconds_bucket (distribution)#

The time it takes to retrieve a connection from the pool.

tuist_http_queue_idle_time_nanoseconds_bucket (distribution)#

The time a connection has been idle waiting to be retrieved.

tuist_http_connection_count (counter)#

The number of connections that have been established.

tuist_http_connection_duration_nanoseconds_sum (sum)#

The time it takes to establish a connection against a host.

tuist_http_connection_duration_nanoseconds_bucket (distribution)#

The distribution of the time it takes to establish a connection against a host.

tuist_http_send_count (counter)#

The number of requests that have been sent once assigned to a connection from the pool.

tuist_http_send_duration_nanoseconds_sum (sum)#

The time that it takes for requests to complete once assigned to a connection from the pool.

tuist_http_send_duration_nanoseconds_bucket (distribution)#

The distribution of the time that it takes for requests to complete once assigned to a connection from the pool.

tuist_http_receive_count (counter)#

The number of responses that have been received from sent requests.

tuist_http_receive_duration_nanoseconds_sum (sum)#

The time spent receiving responses.

tuist_http_receive_duration_nanoseconds_bucket (distribution)#

The distribution of the time spent receiving responses.

tuist_http_queue_available_connections (last_value)#

The number of connections available in the queue.

tuist_http_queue_in_use_connections (last_value)#

The number of queue connections that are in use.