This guide shows you how to run k6 load tests against a Countly server using the bundled load testing suite. The suite includes 5 named scenarios covering script validation, sustained data ingestion, and query load testing. All scenarios live in a single load_test.js file driven by environment variables.
Test against a non-production server
Some scenarios push thousands of requests per second and millions of synthetic users into the target Countly server. Always validate with a single-iteration scenario first on a staging environment. Only run sustained scenarios against a server you control end to end.
Prerequisites
Before you begin, confirm that:
- You have
k6installed locally, or you can run it through Docker. - You have a Countly server URL and an application key (
APP_KEY) to test against. The script has a hardcoded default server and app key for internal use; override both for any other deployment. - For query scenarios (
query_soak,query_single), you also need an API key (API_KEY_QUERY) and application ID (APP_ID_QUERY) with access to the Drill endpoint.
Installing k6
Pick the installation method that matches your platform:
macOS
brew install k6
Linux (Debian or Ubuntu)
sudo gpg -k sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg \ --keyserver hkp://keyserver.ubuntu.com:80 \ --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69 echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" \ | sudo tee /etc/apt/sources.list.d/k6.list sudo apt-get update sudo apt-get install k6
Linux (Fedora or CentOS)
sudo dnf install https://dl.k6.io/rpm/repo.rpm sudo dnf install k6
Windows
choco install k6 # or winget install k6 --source winget
Docker
docker pull grafana/k6 # Browser-enabled image docker pull grafana/k6:master-with-browser
Verify the install:
k6 version
Running Your First Test
The default scenario is single. It sends one session-init request and confirms the script and server connection are working:
k6 run --env COUNTLY_SERVER=https://your-server.com \
--env APP_KEY=your_app_key \
load_test.jsTo run a specific scenario, pass its name via SCENARIO:
k6 run --env SCENARIO=data_generation_soak \
--env COUNTLY_SERVER=https://your-server.com \
--env APP_KEY=your_app_key \
load_test.jsEnvironment variables
SCENARIO defaults to single when omitted. COUNTLY_SERVER and APP_KEY have hardcoded internal defaults; always override them when testing a different deployment. Query scenarios additionally require API_KEY_QUERY and APP_ID_QUERY.
Choosing the Right Scenario
The 5 bundled scenarios cover three test functions. Pick the one that matches the question you are trying to answer:
| Scenario | Profile | Use Case |
|---|---|---|
single | 1 VU, 1 iteration | Script and connection validation (sends one begin_session request) |
data_generation_single | 1 VU, 1 iteration | Single data-generation run for validating the full SDK payload pipeline |
query_single | 1 VU, 1 iteration | Single Drill query run for validating query connectivity and auth |
data_generation_soak | 10 req / 1 s, 600 s | Sustained SDK data ingestion — sessions, events, views, crashes, and user merges |
query_soak | 10 req / 1 s, 600 s | Sustained Drill query load across 13 query types (equality, OR, AND, range, etc.) |
Change the configuration profile for the selected scenarios to match your servers capabilities.
Long scenarios block your terminal
Soak scenarios run for 10 minutes plus a 5-minute graceful stop. Run them in a long-lived session (tmux, screen, or a dedicated VM) and confirm that your shell will not disconnect mid-test. Output to a log file with k6 run … 2>&1 | tee k6-soak.log.
Common Examples
Sustained Data Ingestion
k6 run --env SCENARIO=data_generation_soak \
--env COUNTLY_SERVER=https://test.countly.com \
--env APP_KEY=your_app_key \
load_test.jsSustained Query Load
k6 run --env SCENARIO=query_soak \
--env COUNTLY_SERVER=https://test.countly.com \
--env API_KEY_QUERY=your_api_key \
--env APP_ID_QUERY=your_app_id \
load_test.jsWith Prometheus Remote Write
k6 run --env SCENARIO=data_generation_soak \
--env COUNTLY_SERVER=https://test.countly.com \
--env APP_KEY=your_app_key \
--out experimental-prometheus-rw \
load_test.jsRunning in Docker
docker run --rm -v $(pwd):/k6 \ -e COUNTLY_SERVER=https://your-server.com \ -e APP_KEY=your_app_key \ -e SCENARIO=data_generation_soak \ grafana/k6 run /k6/load_test.js
Sending Results to Prometheus
k6 writes summary statistics to stdout by default. To send live metrics to Prometheus for visualization in Grafana, build a custom k6 binary with the Prometheus remote write extension:
go install go.k6.io/xk6/cmd/xk6@latest xk6 build --with github.com/grafana/xk6-output-prometheus-remote
Then point the build at your Prometheus remote write endpoint and run with the experimental output:
export K6_PROMETHEUS_RW_SERVER_URL=http://localhost:9090/api/v1/write
export K6_PROMETHEUS_RW_TREND_STATS=p(50),p(90),p(95),p(99),max,min
./k6 run --out experimental-prometheus-rw \
--env SCENARIO=data_generation_soak \
--env COUNTLY_SERVER=https://your-server.com \
--env APP_KEY=your_app_key \
load_test.jsIn Grafana, import dashboard 19665 (k6 Prometheus Dashboard) or 18595 (k6 Load Testing Results) for prebuilt visualizations.
Custom Metrics Tracked by the Suite
In addition to standard k6 metrics, the suite tracks Countly-specific business metrics:
session_init_count— session initialization attemptsevents_count— total events sentmerges_count— user merge operationssession_end_count— session end events- Response time trends per query type (Query_01 through Query_15)
- Per-operation success rate
These appear alongside http_req_* metrics in the standard k6 output and in any Prometheus remote write target.
Common Issues and Gotchas
COUNTLY_SERVER is reachable from the host running k6, that APP_KEY is valid, and that no firewall or rate limiter sits between k6 and the server. Run single first to isolate connection issues from load issues.query_soak and query_single scenarios require API_KEY_QUERY and APP_ID_QUERY in addition to APP_KEY. The API key must have access to the Drill endpoint. Run query_single first to confirm credentials before starting a sustained run.K6_PROMETHEUS_RW_SERVER_URL is set and points at the right Prometheus instance. Confirm the k6 binary was built with the Prometheus remote write extension (a stock k6 install does not include it). Confirm the imported Grafana dashboard targets the same Prometheus data source.tmux or screen, on a dedicated host, or in a Kubernetes Job that persists across SSH sessions.