<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Aravind Kannan Rathinasabapathi</title>
    <description>The latest articles on DEV Community by Aravind Kannan Rathinasabapathi (@aravindkannan01).</description>
    <link>https://dev.to/aravindkannan01</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F741656%2Ff2b9d378-9a2c-4c6f-a31d-ea84519f6634.jpeg</url>
      <title>DEV Community: Aravind Kannan Rathinasabapathi</title>
      <link>https://dev.to/aravindkannan01</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aravindkannan01"/>
    <language>en</language>
    <item>
      <title>Every Token Leaves a Trace: Benchmarking Ollama with SigNoz</title>
      <dc:creator>Aravind Kannan Rathinasabapathi</dc:creator>
      <pubDate>Sun, 19 Jul 2026 18:24:40 +0000</pubDate>
      <link>https://dev.to/aravindkannan01/every-token-leaves-a-trace-benchmarking-ollama-with-signoz-g53</link>
      <guid>https://dev.to/aravindkannan01/every-token-leaves-a-trace-benchmarking-ollama-with-signoz-g53</guid>
      <description>&lt;p&gt;Local Large Language Models (&lt;strong&gt;LLMs&lt;/strong&gt;) have made it possible to run powerful AI models entirely on your own machine. They offer greater privacy, eliminate external API costs, and make rapid experimentation much easier. With tools like &lt;strong&gt;Ollama&lt;/strong&gt;, launching a model locally is often as simple as running a single command.&lt;/p&gt;

&lt;p&gt;But once the model starts generating responses, visibility quickly disappears.&lt;/p&gt;

&lt;p&gt;How fast is the model generating tokens? Where is inference time actually spent? And what is the performance impact of moving from a lightweight &lt;strong&gt;1.5B&lt;/strong&gt; model to an &lt;strong&gt;8B&lt;/strong&gt; model?&lt;/p&gt;

&lt;p&gt;These are &lt;strong&gt;observability&lt;/strong&gt; questions.&lt;/p&gt;

&lt;p&gt;Instead of building a benchmark from scratch, we'll build on top of the excellent open-source &lt;code&gt;aidatatools/ollama-benchmark&lt;/code&gt; project. By wrapping it with &lt;strong&gt;OpenTelemetry&lt;/strong&gt;, we'll capture benchmark metrics and export them to &lt;strong&gt;SigNoz&lt;/strong&gt; over &lt;strong&gt;OTLP/HTTP&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;By the end of this guide, you'll have a lightweight observability pipeline that transforms local LLM benchmark runs into &lt;strong&gt;traces, metrics, and dashboards&lt;/strong&gt; you can analyze and compare over time.&lt;/p&gt;




&lt;h2&gt;
  
  
  📋 Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before getting started, ensure you have the following installed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Python 3.10+&lt;/strong&gt;: Required for the benchmarking wrapper.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docker &amp;amp; Docker Compose (v20.10+)&lt;/strong&gt;: Required to run the self-hosted SigNoz stack.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ollama&lt;/strong&gt;: Ensure the Ollama daemon is running (&lt;code&gt;ollama serve&lt;/code&gt;) so the benchmark can execute local inference.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hardware&lt;/strong&gt;: At least &lt;strong&gt;8 GB RAM&lt;/strong&gt; (16 GB or more recommended) to run both SigNoz and local LLMs comfortably.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🏗️ What We Are Building
&lt;/h2&gt;

&lt;p&gt;Instead of waiting for a benchmark to finish and parsing a static text summary, we'll observe the benchmark as it runs.&lt;/p&gt;

&lt;p&gt;Our monitoring pipeline wraps the benchmark execution with OpenTelemetry, capturing performance telemetry in real time and exporting it to SigNoz for visualization and analysis.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────────┐
│ ollama-benchmark │
└────────┬─────────┘
         │ OpenTelemetry
         ▼
┌──────────────────┐
│ Python Wrapper   │
└────────┬─────────┘
         │ OTLP/HTTP :4318
         ▼
┌──────────────────┐
│ SigNoz           │
└──────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🛠️ Step 1: Spin Up SigNoz with Docker Compose
&lt;/h2&gt;

&lt;p&gt;SigNoz is an open-source observability platform that collects and visualizes &lt;strong&gt;metrics&lt;/strong&gt;, &lt;strong&gt;traces&lt;/strong&gt;, and &lt;strong&gt;logs&lt;/strong&gt; in a single interface.&lt;/p&gt;

&lt;p&gt;We'll use &lt;strong&gt;Foundry&lt;/strong&gt;, SigNoz's official configuration CLI, to bootstrap a standalone deployment using Docker Compose.&lt;/p&gt;

&lt;p&gt;Before you begin, ensure Docker Engine (v20.10+) or Docker Desktop is running, then execute the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Download and install the official Foundry management binary wrapper&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://signoz.io/foundry.sh | bash

&lt;span class="c"&gt;# 2. Generate a clean declarative container environment target configuration file&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;&amp;gt; casting.yaml
apiVersion: v1alpha1
kind: Installation
metadata:
  name: signoz
spec:
  deployment:
    flavor: compose
    mode: docker
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="c"&gt;# 3. Trigger the deployment engine pipeline to build configurations and boot the stack&lt;/span&gt;
foundryctl cast &lt;span class="nt"&gt;-f&lt;/span&gt; casting.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;What just happened?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The &lt;code&gt;foundryctl cast&lt;/code&gt; command combines three steps into one:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;gauge&lt;/code&gt;&lt;/strong&gt; validates your system requirements.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;forge&lt;/code&gt;&lt;/strong&gt; generates the required Docker Compose configuration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;cast&lt;/code&gt;&lt;/strong&gt; starts the SigNoz services.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;⚠️ &lt;strong&gt;Common issue:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
ClickHouse requires sufficient memory during startup. If the ClickHouse container crashes or repeatedly restarts with exit code &lt;strong&gt;137&lt;/strong&gt;, increase Docker's memory allocation to at least &lt;strong&gt;4 GB&lt;/strong&gt; under &lt;strong&gt;Docker Desktop → Settings → Resources&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once all containers are healthy, open &lt;strong&gt;&lt;a href="http://localhost:8080" rel="noopener noreferrer"&gt;http://localhost:8080&lt;/a&gt;&lt;/strong&gt; in your browser and create your administrator account.&lt;/p&gt;

&lt;p&gt;SigNoz is now ready to receive OpenTelemetry data on the default OTLP endpoints:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;4317&lt;/strong&gt; (gRPC)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;4318&lt;/strong&gt; (HTTP)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🐍 Step 2: Build the Benchmark Wrapper
&lt;/h2&gt;

&lt;p&gt;Rather than modifying &lt;code&gt;llm-benchmark&lt;/code&gt;, we'll wrap it with a lightweight Python script that adds OpenTelemetry instrumentation. The wrapper forwards benchmark execution to the original library while capturing performance metrics and traces, exporting them to SigNoz in real time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Local Environment Setup
&lt;/h3&gt;

&lt;p&gt;Create a virtual environment, download the wrapper from GitHub Gist, and install the required dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create a virtual environment&lt;/span&gt;
python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv venv

&lt;span class="c"&gt;# Activate it (macOS/Linux)&lt;/span&gt;
&lt;span class="nb"&gt;source &lt;/span&gt;venv/bin/activate

&lt;span class="c"&gt;# Windows&lt;/span&gt;
&lt;span class="c"&gt;# .\venv\Scripts\activate&lt;/span&gt;

&lt;span class="c"&gt;# Download the project files&lt;/span&gt;
curl &lt;span class="nt"&gt;-o&lt;/span&gt; requirements.txt https://gist.githubusercontent.com/Aravind-Kannan/9634d05c7fbe0ebd9be89ca514720b21/raw/bf12809472685c1f60e0f697e54850b6970735e6/requirements.txt
curl &lt;span class="nt"&gt;-o&lt;/span&gt; ollama_bench.py https://gist.githubusercontent.com/Aravind-Kannan/9634d05c7fbe0ebd9be89ca514720b21/raw/f53d04dcbdfedd9c2cdd6f8867b17c258441c8d8/ollama_bench.py

&lt;span class="c"&gt;# Install dependencies&lt;/span&gt;
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--upgrade&lt;/span&gt; pip
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Running the Benchmark
&lt;/h3&gt;

&lt;p&gt;The wrapper supports benchmarking one or more models using standard command-line arguments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Default benchmark (recommended)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run the wrapper without any arguments to benchmark the default set of models:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python ollama_bench.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Single model&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Benchmark a specific model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python ollama_bench.py &lt;span class="nt"&gt;--model&lt;/span&gt; gpt-oss:20b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Multiple models&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Benchmark multiple models in a single run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python ollama_bench.py &lt;span class="nt"&gt;--model&lt;/span&gt; phi4:14b deepseek-r1:14b gpt-oss:20b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2lrapdy2n3olpsyh24uu.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2lrapdy2n3olpsyh24uu.gif" alt="Terminal animation showing the Python benchmark script sequentially pulling 'deepseek-r1:1.5b' and running evaluation prompts. The terminal displays real-time structured logging messages prefixed with 'RunScopedLogger' alongside live token throughput statistics." width="720" height="419"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  💎 Exploring the Distributed Trace
&lt;/h2&gt;

&lt;p&gt;Once the benchmark completes, open the &lt;strong&gt;Traces&lt;/strong&gt; page in SigNoz (&lt;code&gt;http://localhost:8080&lt;/code&gt;) and search for the root span &lt;strong&gt;&lt;code&gt;llm_benchmark_execution&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Each benchmark run is visualized as a hierarchical trace, making it easy to follow the execution flow from model preparation to individual prompt execution.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbzrd3c1zxzc4cabsl2vz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbzrd3c1zxzc4cabsl2vz.png" alt="Distributed trace of a benchmark run in SigNoz" width="800" height="604"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What you'll see
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Model preparation spans&lt;/strong&gt; (&lt;code&gt;pull_model.*&lt;/code&gt;) showing how long each model takes to become ready.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Benchmark spans&lt;/strong&gt; grouping different benchmark categories, such as instruction following, question answering, and vision tasks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model spans&lt;/strong&gt; for each model being evaluated.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prompt spans&lt;/strong&gt; (&lt;code&gt;prompt.0&lt;/code&gt;, &lt;code&gt;prompt.1&lt;/code&gt;, ...) that expose the latency of every prompt within a benchmark.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why this is useful
&lt;/h3&gt;

&lt;p&gt;Instead of relying on a single completion time, you can pinpoint exactly where time is spent during a benchmark. Whether a slowdown comes from pulling a model, a specific benchmark category, or an individual prompt, the waterfall view makes it immediately visible.&lt;/p&gt;




&lt;h2&gt;
  
  
  📊 Building a Performance Dashboard
&lt;/h2&gt;

&lt;p&gt;Now that benchmark telemetry is flowing into SigNoz, let's build a dashboard to compare model performance.&lt;/p&gt;

&lt;p&gt;Navigate to &lt;strong&gt;Dashboards&lt;/strong&gt; → &lt;strong&gt;+ New Dashboard&lt;/strong&gt; and create a dashboard named &lt;strong&gt;Local LLM Performance&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;+ Add Panel&lt;/strong&gt; and configure the following visualizations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Panel 1: Prompt Throughput
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Panel Type:&lt;/strong&gt; Timeseries&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Title:&lt;/strong&gt; &lt;code&gt;Prompt Tokens/sec&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metric:&lt;/strong&gt; &lt;code&gt;llm_benchmark.prompt_tokens_per_sec&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aggregation:&lt;/strong&gt; &lt;code&gt;avg&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Group By:&lt;/strong&gt; &lt;code&gt;model&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This produces a separate throughput trend for each model, making it easy to compare token generation over time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Panel 2: Model Leaderboard
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Panel Type:&lt;/strong&gt; Table&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Title:&lt;/strong&gt; &lt;code&gt;Throughput Leaderboard&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metric:&lt;/strong&gt; &lt;code&gt;llm_benchmark.tokens_per_sec&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aggregation:&lt;/strong&gt; &lt;code&gt;max&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Group By:&lt;/strong&gt; &lt;code&gt;model&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sort the table by &lt;strong&gt;Value&lt;/strong&gt; in &lt;strong&gt;descending&lt;/strong&gt; order to quickly identify the fastest model.&lt;/p&gt;

&lt;h3&gt;
  
  
  Panel 3: Prompt Latency
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Panel Type:&lt;/strong&gt; Bar Chart&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Title:&lt;/strong&gt; &lt;code&gt;Average Prompt Latency&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metric:&lt;/strong&gt; &lt;code&gt;llm_benchmark.prompt_duration_seconds&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aggregation:&lt;/strong&gt; &lt;code&gt;avg&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Group By:&lt;/strong&gt; &lt;code&gt;model&lt;/code&gt;, &lt;code&gt;prompt_index&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This highlights how latency varies across prompts and models.&lt;/p&gt;




&lt;h3&gt;
  
  
  📈 The Final Dashboard
&lt;/h3&gt;

&lt;p&gt;After configuring the panels, your dashboard should provide a consolidated view of model performance, making it easy to compare throughput and latency across benchmark runs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhhy8jwbru7ocandiasaj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhhy8jwbru7ocandiasaj.png" alt="SigNoz Timeseries Panel Configuration" width="800" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Suggested caption:&lt;/strong&gt; &lt;em&gt;The completed Local LLM Performance dashboard comparing throughput and latency across multiple Ollama models.&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Optional: Query with ClickHouse SQL
&lt;/h3&gt;

&lt;p&gt;If you prefer writing SQL instead of using the Query Builder, switch to the &lt;strong&gt;ClickHouse SQL&lt;/strong&gt; tab and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;toStartOfInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="k"&gt;SECOND&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'model'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;avg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;signoz_metrics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;samples_v4&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;metric_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'llm_benchmark.prompt_tokens_per_sec'&lt;/span&gt;
  &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="nb"&gt;timestamp&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="k"&gt;MINUTE&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This query produces the same time-series data used by the &lt;strong&gt;Prompt Throughput&lt;/strong&gt; panel, while giving you full control over aggregation and filtering using ClickHouse SQL.&lt;/p&gt;




&lt;h2&gt;
  
  
  📈 Results &amp;amp; Findings
&lt;/h2&gt;

&lt;p&gt;To validate the observability pipeline, I benchmarked three Ollama models on the following hardware:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Hardware&lt;/th&gt;
&lt;th&gt;Specification&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Laptop&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Apple M3 Pro&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Memory&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;36 GB RAM&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Benchmark Results
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Peak Throughput (Tokens/sec)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;gpt-oss:20b&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;30.71&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;deepseek-r1:14b&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;13.60&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;phi4:14b&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;13.22&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Key takeaway:&lt;/strong&gt; On this particular machine and benchmark configuration, &lt;strong&gt;gpt-oss:20b&lt;/strong&gt; delivered the highest token throughput, more than doubling the throughput of the two 14B models.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Higher throughput does &lt;strong&gt;not&lt;/strong&gt; necessarily mean a model is &lt;em&gt;better&lt;/em&gt;. It simply means the model generated tokens faster under this specific workload on my Apple M3 Pro laptop. Model quality, reasoning ability, accuracy, latency, memory usage, and suitability for a task are independent factors that should also be considered.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is exactly why observability matters. Rather than assuming larger or newer models will perform better, you can use traces, metrics, and dashboards to measure how different models behave on your own hardware.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 Conclusion
&lt;/h2&gt;

&lt;p&gt;By combining &lt;code&gt;aidatatools/ollama-benchmark&lt;/code&gt;, OpenTelemetry, and SigNoz, we've transformed a simple benchmark script into an observable benchmarking pipeline. Instead of relying on terminal output alone, every benchmark run is captured as traces and metrics that can be explored, compared, and analyzed over time.&lt;/p&gt;

&lt;p&gt;The same approach can be applied to many existing CLI tools—adding observability without modifying their source code. Whether you're comparing lightweight 1.5B models or larger 8B models, OpenTelemetry provides the visibility needed to understand where time is spent and how performance changes across runs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Every token leaves a trace.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🚀 What's Next?
&lt;/h3&gt;

&lt;p&gt;Clone the project, run the benchmark against your favorite Ollama models, and explore the results in SigNoz. Extend the dashboard with your own metrics, compare different hardware configurations, or instrument additional benchmarking tools using the same pattern.&lt;/p&gt;

&lt;p&gt;If you build on this project or discover interesting performance insights, I'd love to hear about your findings!&lt;/p&gt;




&lt;h2&gt;
  
  
  📚 References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SigNoz Documentation&lt;/strong&gt; – &lt;a href="https://signoz.io/docs/" rel="noopener noreferrer"&gt;https://signoz.io/docs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SigNoz GitHub Repository&lt;/strong&gt; – &lt;a href="https://github.com/SigNoz/signoz" rel="noopener noreferrer"&gt;https://github.com/SigNoz/signoz&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OpenTelemetry Documentation&lt;/strong&gt; – &lt;a href="https://opentelemetry.io/docs/" rel="noopener noreferrer"&gt;https://opentelemetry.io/docs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OpenTelemetry Python SDK&lt;/strong&gt; – &lt;a href="https://opentelemetry.io/docs/languages/python/" rel="noopener noreferrer"&gt;https://opentelemetry.io/docs/languages/python/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ollama Documentation&lt;/strong&gt; – &lt;a href="https://ollama.com/" rel="noopener noreferrer"&gt;https://ollama.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;aidatatools/ollama-benchmark&lt;/strong&gt; – &lt;a href="https://github.com/aidatatools/ollama-benchmark" rel="noopener noreferrer"&gt;https://github.com/aidatatools/ollama-benchmark&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ClickHouse Documentation&lt;/strong&gt; – &lt;a href="https://clickhouse.com/docs" rel="noopener noreferrer"&gt;https://clickhouse.com/docs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
  </channel>
</rss>
