MooBench: A micro-benchmark for performance overhead measurement of observability tools

MooBench: A micro-benchmark for performance overhead measurement of observability tools - Published in JOSS (2026)

https://github.com/kieker-monitoring/moobench

Science Score: 95.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
    Found CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
  • DOI references
    Found 1 DOI reference(s) in JOSS metadata
  • Academic publication links
  • Academic email domains
  • Institutional organization owner
  • JOSS paper metadata
    Published in Journal of Open Source Software

Keywords

apm benchmark benchmarking observability tracing
Last synced: 6 days ago · JSON representation ·

Repository

Micro-benchmarks for quantification of the performance overhead caused by observability frameworks

Basic Info
  • Host: GitHub
  • Owner: kieker-monitoring
  • License: apache-2.0
  • Language: Shell
  • Default Branch: main
  • Homepage:
  • Size: 414 MB
Statistics
  • Stars: 7
  • Watchers: 5
  • Forks: 9
  • Open Issues: 11
  • Releases: 3
Topics
apm benchmark benchmarking observability tracing
Created over 4 years ago · Last pushed 13 days ago
Metadata Files
Readme Contributing License Citation Codemeta

README.md

The MooBench Observability Overhead Micro-Benchmark

The MooBench micro-benchmarks can be used to quantify the performance overhead caused by observability framework components and different observability frameworks. Observability is achieved through its three pillars: * Logs, i.e., timestamped information about system events, * Metrics, i.e., numerical measurements of system behaviour, and * Traces, i.e., representations of request, transaction or operation executions.

MooBench can measure the overhead that is created by obtaining any of these three pillars of observability from program execution.

Continuous measurement results are available here: * Kiel University Server (Intel Xeon CPU E5620 @ 2.40 GHz, Debian 12): https://kieker-monitoring.net/performance-benchmarks/ * GH Actions Runner (Ubuntu 24.04 -- see .github/workflows/benchmark*.yaml for curent version): https://kieker-monitoring.github.io/moobench-data/dev/bench/

Currenly (fully) supported observability frameworks are: * Elastic APM with Java (https://github.com/elastic/apm-agent-java) * inspectIT with Java (https://inspectit.rocks/) * Kieker with Java (http://kieker-monitoring.net) * OpenTelemetry with Java (https://opentelemetry.io/) * PinPoint with Java (https://github.com/pinpoint-apm/pinpoint) * Scouter with Java (https://github.com/scouter-project/scouter)

For all combinations of supported observability frameworks $FRAMEWORK and languages $LANGUAGE, the folder frameworks contains a folder $FRAMEWORK-$LANGUAGE.

Approach

MooBenchs measures the overhead of gathering observability data by executing an example workload using different configurations, including no instrumentation (and hence no data gathering) at all, full distributed tracing and data serialization via binary writer. The example workload consists of $RECURSION_DEPTH recursive calls of a function to itself. For example, the following graph shows the execution of MooBench in the no instrumentation configuration:

mermaid graph TD; BenchmarkingThreadNano.run-->MonitoredClassSimple.monitoredMethod; MonitoredClassSimple.monitoredMethod-->MonitoredClassSimple.monitoredMethod; MonitoredClassSimple.monitoredMethod-->id["Busy Wait"]

The binary writer configuration on the other hand includes the probe code, that is injected by the observability tool before and after the operation. For the Kieker monitoring framework, the probe inserts records into the WriterController.writerQueue, and these are then processed for finally writing binary data to the hard disk.

mermaid flowchart TD; instrumentedCall["`probeBeforeOperation() MonitoredClassSimple.monitoredMethod probeAfterOperation`"] BenchmarkingThreadNano.run-->instrumentedCall; instrumentedCall-->instrumentedCall; instrumentedCall-->id["Busy Wait"]; subgraph Kieker direction LR WriterController.writerQueue-->FileWriter.writeMonitoringRecord; FileWriter.writeMonitoringRecord-->BinaryLogStreamHandler.serialize; end instrumentedCall-->Kieker;

Benchmark Execution

By one execution of the MooBench, we can measure the overhead of one observability framework.

Prerequisites

To use MooBench, please make sure the following tools are installed: - A linux system, capable of running bash 5.x (or newer), including curl and awk (sudo dnf install gawk curl) - A recent R installation (Rocky Linux: sudo dnf install epel-release; sudo dnf config-manager --set-enabled crb; sudo dnf install R) - For Pinpoint and Skywalking: Docker 28.0.0 or newer (for containers that manage observability data persistence) - For Java agents (Kieker, OpenTelemetry, Pinpoint, inspectIT, Skywalking) * A recent JDK installation (OpenJDK 17 or newer); $JAVA_HOME needs to be set - For Python agents (Kieker, OpenTelemetry) * Python 3.11 or newer

Benchmark Execution

Compile the application and install it in the repository root directory. This can be done automatically be calling ./setup.sh. Afterwards, you can switch to the benchmark folder (frameworks and then $AGENT-$TECHNOLOGY, e.g., OpenTelemetry as observability agent in Java) and run ./benchmark.sh.

For example, a simple benchmark execution is: ./setup.sh cd frameworks/OpenTelemetry-java/ ./measure.sh

After each run, the main results are displayed in stdout, for example:

1 2 3 4 5 6 mean " 0.2300" " 7.8581" " NA" " 10.5748" " 11.0599" " NA" sd " 0.1356" "115.0105" " NA" " 3.2623" " 3.4707" " NA" ci95% " 0.0038" " 3.1879" " NA" " 0.0904" " 0.0962" " NA" md25% " 0.1900" " 4.2380" " NA" " 8.0750" " 8.7310" " NA" md50% " 0.1910" " 4.5580" " NA" " 11.2710" " 11.3110" " NA" md75% " 0.2800" " 8.0450" " NA" " 11.5620" " 12.5040" " NA" max " 6.5920" "8135.7560" " NA" " 89.2280" " 99.5470" " NA" min " 0.1800" " 4.0970" " NA" " 7.5140" " 7.0230" " NA" For each configuration (1-6), this gives us statistics of the execution. For example, here we see that configuration 4 (Writing OpenTelemetry traces to Zipkin) has a mean execution time of 10.5748 microseconds and configuration 0 (baseline, no instrumentation at all) has an a mean execution time of 0.2300 microseconds.

All experiments are started with the provided "External Controller" scripts. The following scripts are available for every supported framework ($FRAMEWORK) and language ($LANGUAGE): * In frameworks/$FRAMEWORK-$LANGUAGE/measure.sh a script is provided for regular execution (with default parameters) * In frameworks/$FRAMEWORK-$LANGUAGE/runExponentialSizes.sh a script is provided for execution with different call tree depth sizes (exponentially growing from 2)

Each scripts will start different factorial experiments (started $NUM_OF_LOOPS times for repeatability), which will be: - baseline execution - execution with instrumentation but without processing or serialization - execution with serialization to hard disc (currently not available for inspectIT) - execution with serialization to tcp receiver, which might be a simple receiver (Kieker), or Zikpin and Prometheus (OpenTelemetry and inspectIT)

All scripts have been tested on Ubuntu, Rocky 9.6 and Raspbian.

The execution may be parameterized by the following environment variables: * SLEEP_TIME between executions (default 30 seconds) * NUM_OF_LOOPS number of repetitions (default 10) * THREADS concurrent benchmarking threads (default 1) * RECURSION_DEPTH recursion up to this depth (default 10) * TOTAL_NUM_OF_CALLS the duration of the benchmark (deafult 2,000,000 calls) * METHOD_TIME the time per monitored call (default 0 ns or 500 us)

If they are unset, the values are set via frameworks/common-function.sh.

Formatting

All shell files should be formatted using shfmt -w -i 2 -sr -kp.

Data Analysis

Each benchmark execution calls an R script providing mean, standard deviation and confidence intervals for the benchmark variants. If you want to get these values again, switch to frameworks and call runR.sh $FRAMEWORK, where framework is the folder name of the framework (e.g. Kieker).

If you got data from a run with exponential growing call tree depth, unzip them first (for file in *.zip; do unzip $file; done), copy all results-$framework folder to a common folder and run ./getExponential.sh in analysis. This will create a graph for each framework and an overview graph for external processing of the traces (zipkin for OpenTelemetry and inspectIT, TCP for Kieker).

In the folder /bin/r are some R scripts provided to generate graphs to visualize the results. In the top the files, one can configure the required paths and the configuration used to analyze the data.

Quality Control

We also use MooBench as a performance regression test which is run periodically when new features are added to Kieker.

Owner

  • Name: kieker-monitoring
  • Login: kieker-monitoring
  • Kind: organization

JOSS Publication

MooBench: A micro-benchmark for performance overhead measurement of observability tools
Published
July 07, 2026
Volume 11, Issue 123, Page 10400
Authors
David Georg Reichelt ORCID
Lancaster University Leipzig, Universitätsrechenzentrum (URZ) Leipzig
Shinhyung Yang ORCID
Kiel University
Marcel Hansson ORCID
University of Hamburg
Wilhelm Hasselbring ORCID
Kiel University
Editor
Jack Atkinson ORCID
Tags
Java ...

Citation (CITATION.cff)

# YAML 1.2
---
abstract: "MooBench is a micro-benchmark for quantification of the performance overhead caused by observability frameworks. It consists of a minimal system under test for injection of observability frameworks, the automation of the overhead measurement process and analysis scripts."
authors:
  -
    affiliation: "Lancaster University"
    family-names: Reichelt
    given-names: David Georg
    orcid: "https://orcid.org/0000-0002-1772-1416"
  -
    affiliation: "Kiel University"
    family-names: Yang
    given-names: Shinhyung
    orcid: "https://orcid.org/0000-0002-8997-9942"
  -
    affiliation: "University of Hamburg"
    family-names: Hansson
    given-names: Marcel
    orcid: "https://orcid.org/0009-0000-6524-037X"
  -
    affiliation: "Kiel University"
    family-names: Hasselbring
    given-names: Wilhelm
    orcid: "https://orcid.org/0000-0001-6625-4335"
cff-version: "1.2.0"
doi: "10.5281/zenodo.19386366"
keywords:
  - "Observability Engineering"
  - "Tracing"
  - "Benchmark"
  - "Application Performance Monitoring"
  - "Monitoring Framework"
license: "Apache-2.0"
message: "If you use this software, please cite https://doi.org/10.5281/zenodo.19386366"
repository-code: "https://github.com/kieker-monitoring/moobench"
title: MooBench
version: "1.0.1"

CodeMeta (codemeta.json)

{
  "@context": "https://raw.githubusercontent.com/codemeta/codemeta/master/codemeta.jsonld",
  "@type": "Code",
  "author": [
    {
      "@id": "https://orcid.org/0000-0002-1772-1416",
      "@type": "Person",
      "email": "d.g.reichelt@lancaster.ac.uk",
      "name": "David Georg Reichelt",
      "affiliation": "Lancaster University Leipzig"
    },
    {
      "@type": "Person",
      "@id": "https://orcid.org/0000-0002-5464-8561",
      "givenName": "Reiner",
      "familyName": "Jung",
      "email": "reiner.jung@stk.landsh.de",
      "affiliation": {
        "@type": "Organization",
        "name": "ZIT SH"
      }
    },
    {
      "@type": "Person",
      "@id": "https://orcid.org/0000-0001-6625-4335",
      "givenName": "Wilhelm",
      "familyName": "Hasselbring",
      "email": "hasselbring@email.uni-kiel.de",
      "affiliation": {
        "@type": "Organization",
        "name": "Kiel University"
      }
    },
    {
      "@type": "Person",
      "@id": "https://orcid.org/0000-0002-8997-9942",
      "givenName": "Shinhyung",
      "familyName": "Yang",
      "email": "shinhyung.yang@email.uni-kiel.de",
      "affiliation": {
        "@type": "Organization",
        "name": "Kiel University"
      }
    },
    {
      "@type": "Person",
      "@id": "https://orcid.org/0009-0000-6524-037X",
      "givenName": "Marcel",
      "familyName": "Hansson",
      "email": "marcel.hansson@uni-hamburg.de",
      "affiliation": {
        "@type": "Organization",
        "name": "University of Hamburg"
      }
    }
  ],
  "identifier": "https://doi.org/10.5281/zenodo.19386366",
  "codeRepository": "https://github.com/kieker-monitoring/moobench",
  "datePublished": "2026-04-02",
  "dateModified": "2026-04-02",
  "dateCreated": "2013-10-15",
  "description": "MooBench is a micro-benchmark for quantification of the performance overhead caused by observability frameworks. It consists of a minimal system under test for injection of observability frameworks, the automation of the overhead measurement process and analysis scripts.",
  "keywords": "Observability Engineering, Tracing, Benchmark, Application Performance Monitoring",
  "license": "Apache 2.0",
  "title": "MooBench",
  "version": "v1.0.1"
}

GitHub Events

Total
  • Delete event: 3
  • Pull request event: 20
  • Fork event: 3
  • Issues event: 9
  • Watch event: 5
  • Issue comment event: 40
  • Push event: 2,862
  • Pull request review event: 7
  • Pull request review comment event: 6
  • Create event: 9
  • Commit comment event: 2
Last Year
  • Delete event: 1
  • Pull request event: 5
  • Fork event: 2
  • Issues event: 4
  • Watch event: 3
  • Issue comment event: 10
  • Push event: 857
  • Pull request review comment event: 4
  • Pull request review event: 5
  • Create event: 4
  • Commit comment event: 1

Issues and Pull Requests

Last synced: 3 months ago

All Time
  • Total issues: 7
  • Total pull requests: 13
  • Average time to close issues: 4 months
  • Average time to close pull requests: 11 days
  • Total issue authors: 2
  • Total pull request authors: 2
  • Average comments per issue: 0.86
  • Average comments per pull request: 2.08
  • Merged pull requests: 7
  • Bot issues: 0
  • Bot pull requests: 0
Past Year
  • Issues: 1
  • Pull requests: 2
  • Average time to close issues: N/A
  • Average time to close pull requests: 22 minutes
  • Issue authors: 1
  • Pull request authors: 2
  • Average comments per issue: 0.0
  • Average comments per pull request: 0.5
  • Merged pull requests: 1
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
  • DaGeRe (6)
  • shinhyungyang (1)
Pull Request Authors
  • shinhyungyang (8)
  • Marcel-Ha (5)
Top Labels
Issue Labels
Pull Request Labels

Dependencies

build.gradle maven
  • com.beust:jcommander 1.72 implementation
  • com.google.guava:guava 29.0-jre implementation
  • junit:junit 4.13 testImplementation
tools/benchmark/build.gradle maven
  • com.beust:jcommander 1.72 implementation
tools/compile-results/build.gradle maven
  • ch.qos.logback:logback-classic 1.2.3 implementation
  • com.beust:jcommander 1.78 implementation
  • com.fasterxml.jackson.core:jackson-databind 2.11.3 implementation
  • net.kieker-monitoring:kieker 2.0.0-SNAPSHOT implementation
  • net.sourceforge.teetime:teetime 3.1-SNAPSHOT implementation
  • org.apache.commons:commons-csv 1.8 implementation
tools/receiver/build.gradle maven
  • ch.qos.logback:logback-classic 1.2.3 implementation
  • net.kieker-monitoring:kieker 1.14 implementation
  • net.sourceforge.teetime:teetime 3.0 implementation
.github/workflows/buildBenchmark.yaml actions
  • actions/checkout v2 composite
  • actions/setup-java v1 composite
.github/workflows/executeInspectITJava.yaml actions
  • actions/checkout v2 composite
  • actions/setup-java v1 composite
.github/workflows/executeKiekerJava.yaml actions
  • actions/checkout v2 composite
  • actions/setup-java v1 composite
.github/workflows/executeKiekerPython.yaml actions
  • actions/checkout v2 composite
  • actions/setup-java v1 composite
.github/workflows/executeOpenTelemetryJava.yaml actions
  • actions/checkout v2 composite
  • actions/setup-java v1 composite
docker/Dockerfile docker
  • openjdk 17-jdk-alpine3.14 build
frameworks/SPASSmeter/build.gradle maven