Demo app for learning observability with Grafana and performance testing with k6.
166
stars
508
commits
Go
primary language
Sep 10, 2026
updated

QuickPizza is a simple web application, used for demonstrations and workshops, that generates new and exciting pizza combinations!
It helps you learn app instrumentation and observability with the Grafana stack, and k6 testing from basics to advanced.
You can run QuickPizza locally or deploy it to your own infrastructure. For demo purposes, QuickPizza is also publicly available at:
The requirements for QuickPizza depend on your intended useβwhether you want to run k6 tests for performance testing, or enable observability with a local or Grafana Cloud observability stack.
All tests live in the k6 folder. Within this folder, you will find the following folders:
To run tests on the foundations folder, you can use the following commands:
cd k6/foundations
k6 run 01.basic.js
If QuickPizza is publicly available , then pass the hostname and port through the BASE_URL environment variable as follows:
k6 run -e BASE_URL=https://quickpizza.grafana.com 01.basic.js
cd k6/extensions
xk6 build --with xk6-internal=../internal
To run the test that uses the k6/x/internal module, use previously created k6 binary in the k6/extensions folder:
./k6 run 01.basic-internal.js
You can also send k6 metrics to either a local Prometheus instance or Grafana Cloud Prometheus, and visualize the test results in Grafana.
./k6 run -o experimental-prometheus-rw 01.basic-internal.js
The sections below explain how to observe QuickPizza using either a local Grafana Observability stack or Grafana Cloud.
For detailed instructions, see Send k6 Test Results to Prometheus
If you want to use the k6 Docker image to run k6, you need to run the QuickPizza and k6 containers within the same network.
First, create a Docker network. Then, run QuickPizza, assigning a hostname and connecting to the created network.
docker network create quickpizza_network
docker run --network=quickpizza_network --hostname=quickpizza --rm -it -p 3333:3333 ghcr.io/grafana/quickpizza-local:latest
Next, you can use the k6 Docker image to execute the k6 test. Run the k6 Docker container within the same network (quickpizza_network) and pass the BASE_URL environment variable with the value of the QuickPizza container's hostname as follows:
docker run -i --network=quickpizza_network -e BASE_URL=http://quickpizza:3333 grafana/k6 run - <01.basic.js
To run the app locally with Docker, run the command:
docker run --rm -it -p 3333:3333 ghcr.io/grafana/quickpizza-local:latest
or build image from the repo:
docker run --rm -it -p 3333:3333 $(docker build -q .)
That's it!
Now you can go to localhost:3333 and get some pizza recommendations!
Testing something you can't observe is only half the fun! πβ¨ QuickPizza is instrumented using best practices to record logs, emit metrics, traces and allow profiling. Get ready to dive deep into observability! π
The compose.grafana-local-stack.monolithic.yaml file is set up to run and orchestrate the QuickPizza, Grafana, Tempo, Loki, Prometheus, Pyroscope, and Grafana Alloy containers.
Grafana Alloy collects traces, metrics, logs and profiling data from the QuickPizza app, forwarding them to the Tempo, Prometheus and Loki. Finally, you can visualize and correlate data stored in these containers with the locally running Grafana instance.
To start the local environment with the complete observability stack, use the following command:
docker compose -f compose.grafana-local-stack.monolithic.yaml up -d
This setup runs QuickPizza in monolithic mode, where all QuickPizza components run in a single instance.
Like before, QuickPizza is available at localhost:3333. It's time to discover some fancy pizzas!
Then, you can visit the Grafana instance running at localhost:3000 and use Explore or Drilldown apps to access QuickPizza data.

QuickPizza can be deployed in two modes: monolithic or microservices.
catalog, recommendations, or public-api). Each service runs in its own Docker container.The microservices architecture demonstrates service-oriented observability patterns, such as distributed tracing, metric labeling per service, and log correlation.
graph TB
subgraph "QuickPizza microservices"
subgraph public-api-svc [public-api service]
API[/gateway component/]
FR[/frontend component/]
end
copy-svc[copy service]
rec-svc[recommendations service]
cfg-svc[config service]
ws-svc[ws service]
subgraph catalog-svc [catalog service]
CA[/catalog component/]
US[/users component/]
AD[/admin component/]
end
DB[(db)]
end
GA[Alloy]
GC[Grafana Cloud<br/>Mimir, Loki, Tempo, Pyroscope]
User --> FR
API_Client --> API
FR --> API
API --> copy-svc
API --> rec-svc
API --> cfg-svc
API --> ws-svc
API --> CA
API --> US
API --> AD
copy-svc --> DB
catalog-svc --> DB
public-api-svc <--> GA
catalog-svc <--> GA
copy-svc <--> GA
rec-svc <--> GA
cfg-svc <--> GA
ws-svc <--> GA
GA --> GC
Label and attributes follow OpenTelemetry semantic conventions for service-oriented architectures:
Observability labels:
service_namespace=quickpizzaservice_name={catalog, config, public-api, ...}OTEL resource attributes:
service.namespace=quickpizzaservice.name={catalog, config, public-api, ...}Observability labels:
service_namespace=quickpizzaservice_name=quickpizzaOTEL resource attributes:
service.namespace=quickpizzaservice.name=quickpizzaservice.component={catalog, config, public-api, ...}You can deploy QuickPizza with different Compose files depending on the mode and observability backend:
compose.grafana-local-stack.monolithic.yaml: Monolithic mode with a local Grafana observability stack.compose.grafana-local-stack.microservices.yaml: Microservice mode with a local Grafana observability stack.compose.grafana-cloud.monolithic.yaml: Monolithic mode with Grafana Cloud.compose.grafana-cloud.microservices.yaml: Microservice mode with Grafana Cloud.For microservice deployments, we recommend monitoring QuickPizza with Application Observability, which allows you to easily visualize and correlate data across services.
The compose.grafana-cloud.microservices.yaml file is set up to run QuickPizza in microservice mode with a Grafana Alloy instance.
In this setup, Grafana Alloy collects observability data from the QuickPizza microservices and forwards it to Grafana Cloud.
You will need the following settings:
stacks:read, metrics:write, logs:write, traces:write, and profiles:write.Then, create an .env file with the following environment variables and the values of the previous settings:
# Your Grafana Cloud Stack Name (Slug)
GRAFANA_CLOUD_STACK=
# Your Grafana Cloud Access Policy Token
GRAFANA_CLOUD_TOKEN=
Finally, execute the Docker Compose command using the compose.grafana-cloud.microservices.yaml file, just as in the local setup:
docker compose -f compose.grafana-cloud.microservices.yaml up -d
QuickPizza is available at localhost:3333. Click the Pizza, Please! button and discover some awesome pizzas!
Now, you can log in to Grafana Cloud and use Explore or Drilldown apps to access QuickPizza's telemetry data.


The Docker Compose setup is fully instrumented out of the box, so you can jump right into Grafana Cloud Observability apps and start observing the inner workings of the QuickPizza service components.
To enable Application Observability and Database Observability for QuickPizza:



To enable Grafana Cloud Frontend Observability:
In Grafana Cloud, create a new Frontend Observability application and set the domain to http://localhost:3333.
Copy the application's Faro web URL.
In your .env file, add the following environment variables to configure your Faro URL and application name:
# FRONTEND OBSERVABILITY URL
QUICKPIZZA_CONF_FARO_URL=
# FRONTEND OBSERVABILITY APPLICATION NAME
QUICKPIZZA_CONF_FARO_APP_NAME=
# ENABLE FARO SESSION REPLAY INSTRUMENTATION (default: false)
QUICKPIZZA_CONF_FARO_INSTRUMENTATION_ENABLE_REPLAY=true
Restart the compose.grafana-cloud.microservices.yaml environment:
docker compose -f compose.grafana-cloud.microservices.yaml down
docker compose -f compose.grafana-cloud.microservices.yaml up -d

Go
42.1%
JavaScript
20.5%
HCL
13.8%
Svelte
10.6%
HTML
6.3%
Shell
2.0%
CSS
1.8%
TypeScript
1.8%
Demo app for learning observability with Grafana and performance testing with k6.
166
stars
508
commits
Go
primary language
Sep 10, 2026
updated

QuickPizza is a simple web application, used for demonstrations and workshops, that generates new and exciting pizza combinations!
It helps you learn app instrumentation and observability with the Grafana stack, and k6 testing from basics to advanced.
You can run QuickPizza locally or deploy it to your own infrastructure. For demo purposes, QuickPizza is also publicly available at:
The requirements for QuickPizza depend on your intended useβwhether you want to run k6 tests for performance testing, or enable observability with a local or Grafana Cloud observability stack.
All tests live in the k6 folder. Within this folder, you will find the following folders:
To run tests on the foundations folder, you can use the following commands:
cd k6/foundations
k6 run 01.basic.js
If QuickPizza is publicly available , then pass the hostname and port through the BASE_URL environment variable as follows:
k6 run -e BASE_URL=https://quickpizza.grafana.com 01.basic.js
cd k6/extensions
xk6 build --with xk6-internal=../internal
To run the test that uses the k6/x/internal module, use previously created k6 binary in the k6/extensions folder:
./k6 run 01.basic-internal.js
You can also send k6 metrics to either a local Prometheus instance or Grafana Cloud Prometheus, and visualize the test results in Grafana.
./k6 run -o experimental-prometheus-rw 01.basic-internal.js
The sections below explain how to observe QuickPizza using either a local Grafana Observability stack or Grafana Cloud.
For detailed instructions, see Send k6 Test Results to Prometheus
If you want to use the k6 Docker image to run k6, you need to run the QuickPizza and k6 containers within the same network.
First, create a Docker network. Then, run QuickPizza, assigning a hostname and connecting to the created network.
docker network create quickpizza_network
docker run --network=quickpizza_network --hostname=quickpizza --rm -it -p 3333:3333 ghcr.io/grafana/quickpizza-local:latest
Next, you can use the k6 Docker image to execute the k6 test. Run the k6 Docker container within the same network (quickpizza_network) and pass the BASE_URL environment variable with the value of the QuickPizza container's hostname as follows:
docker run -i --network=quickpizza_network -e BASE_URL=http://quickpizza:3333 grafana/k6 run - <01.basic.js
To run the app locally with Docker, run the command:
docker run --rm -it -p 3333:3333 ghcr.io/grafana/quickpizza-local:latest
or build image from the repo:
docker run --rm -it -p 3333:3333 $(docker build -q .)
That's it!
Now you can go to localhost:3333 and get some pizza recommendations!
Testing something you can't observe is only half the fun! πβ¨ QuickPizza is instrumented using best practices to record logs, emit metrics, traces and allow profiling. Get ready to dive deep into observability! π
The compose.grafana-local-stack.monolithic.yaml file is set up to run and orchestrate the QuickPizza, Grafana, Tempo, Loki, Prometheus, Pyroscope, and Grafana Alloy containers.
Grafana Alloy collects traces, metrics, logs and profiling data from the QuickPizza app, forwarding them to the Tempo, Prometheus and Loki. Finally, you can visualize and correlate data stored in these containers with the locally running Grafana instance.
To start the local environment with the complete observability stack, use the following command:
docker compose -f compose.grafana-local-stack.monolithic.yaml up -d
This setup runs QuickPizza in monolithic mode, where all QuickPizza components run in a single instance.
Like before, QuickPizza is available at localhost:3333. It's time to discover some fancy pizzas!
Then, you can visit the Grafana instance running at localhost:3000 and use Explore or Drilldown apps to access QuickPizza data.

QuickPizza can be deployed in two modes: monolithic or microservices.
catalog, recommendations, or public-api). Each service runs in its own Docker container.The microservices architecture demonstrates service-oriented observability patterns, such as distributed tracing, metric labeling per service, and log correlation.
graph TB
subgraph "QuickPizza microservices"
subgraph public-api-svc [public-api service]
API[/gateway component/]
FR[/frontend component/]
end
copy-svc[copy service]
rec-svc[recommendations service]
cfg-svc[config service]
ws-svc[ws service]
subgraph catalog-svc [catalog service]
CA[/catalog component/]
US[/users component/]
AD[/admin component/]
end
DB[(db)]
end
GA[Alloy]
GC[Grafana Cloud<br/>Mimir, Loki, Tempo, Pyroscope]
User --> FR
API_Client --> API
FR --> API
API --> copy-svc
API --> rec-svc
API --> cfg-svc
API --> ws-svc
API --> CA
API --> US
API --> AD
copy-svc --> DB
catalog-svc --> DB
public-api-svc <--> GA
catalog-svc <--> GA
copy-svc <--> GA
rec-svc <--> GA
cfg-svc <--> GA
ws-svc <--> GA
GA --> GC
Label and attributes follow OpenTelemetry semantic conventions for service-oriented architectures:
Observability labels:
service_namespace=quickpizzaservice_name={catalog, config, public-api, ...}OTEL resource attributes:
service.namespace=quickpizzaservice.name={catalog, config, public-api, ...}Observability labels:
service_namespace=quickpizzaservice_name=quickpizzaOTEL resource attributes:
service.namespace=quickpizzaservice.name=quickpizzaservice.component={catalog, config, public-api, ...}You can deploy QuickPizza with different Compose files depending on the mode and observability backend:
compose.grafana-local-stack.monolithic.yaml: Monolithic mode with a local Grafana observability stack.compose.grafana-local-stack.microservices.yaml: Microservice mode with a local Grafana observability stack.compose.grafana-cloud.monolithic.yaml: Monolithic mode with Grafana Cloud.compose.grafana-cloud.microservices.yaml: Microservice mode with Grafana Cloud.For microservice deployments, we recommend monitoring QuickPizza with Application Observability, which allows you to easily visualize and correlate data across services.
The compose.grafana-cloud.microservices.yaml file is set up to run QuickPizza in microservice mode with a Grafana Alloy instance.
In this setup, Grafana Alloy collects observability data from the QuickPizza microservices and forwards it to Grafana Cloud.
You will need the following settings:
stacks:read, metrics:write, logs:write, traces:write, and profiles:write.Then, create an .env file with the following environment variables and the values of the previous settings:
# Your Grafana Cloud Stack Name (Slug)
GRAFANA_CLOUD_STACK=
# Your Grafana Cloud Access Policy Token
GRAFANA_CLOUD_TOKEN=
Finally, execute the Docker Compose command using the compose.grafana-cloud.microservices.yaml file, just as in the local setup:
docker compose -f compose.grafana-cloud.microservices.yaml up -d
QuickPizza is available at localhost:3333. Click the Pizza, Please! button and discover some awesome pizzas!
Now, you can log in to Grafana Cloud and use Explore or Drilldown apps to access QuickPizza's telemetry data.


The Docker Compose setup is fully instrumented out of the box, so you can jump right into Grafana Cloud Observability apps and start observing the inner workings of the QuickPizza service components.
To enable Application Observability and Database Observability for QuickPizza:



To enable Grafana Cloud Frontend Observability:
In Grafana Cloud, create a new Frontend Observability application and set the domain to http://localhost:3333.
Copy the application's Faro web URL.
In your .env file, add the following environment variables to configure your Faro URL and application name:
# FRONTEND OBSERVABILITY URL
QUICKPIZZA_CONF_FARO_URL=
# FRONTEND OBSERVABILITY APPLICATION NAME
QUICKPIZZA_CONF_FARO_APP_NAME=
# ENABLE FARO SESSION REPLAY INSTRUMENTATION (default: false)
QUICKPIZZA_CONF_FARO_INSTRUMENTATION_ENABLE_REPLAY=true
Restart the compose.grafana-cloud.microservices.yaml environment:
docker compose -f compose.grafana-cloud.microservices.yaml down
docker compose -f compose.grafana-cloud.microservices.yaml up -d

Go
42.1%
JavaScript
20.5%
HCL
13.8%
Svelte
10.6%
HTML
6.3%
Shell
2.0%
CSS
1.8%
TypeScript
1.8%