Trafficinator is a load testing tool built to generate realistic traffic patterns for Matomo.
It helps you stress test Matomo’s frontend performance when handling large datasets in reports, so you can identify bottlenecks and optimize configuration for high-traffic websites.
-
🎨 Modern Web Control UI
- Visual dashboard with real-time status monitoring
- Configuration form with validation and test connection
- Load presets (Light/Medium/Heavy/Extreme) for quick setup
- Live log viewer with filtering and search
- Secure API with authentication and rate limiting
- REST API for programmatic control and automation
-
Realistic traffic simulation
- Generates 3–6 pageviews per visit with natural timing between requests
- Rotates user agents and URLs to create diverse report data
- Site search simulation with configurable probability and realistic search terms
- Outlinks and downloads tracking with external URLs and file downloads
- Custom events tracking with click events and random user interactions
- Conversion funnels with configurable multi-step journeys and delays
- Ecommerce orders simulation with realistic product catalog and purchase flows
- Extended visit durations of 1-8 minutes for realistic engagement metrics
- Traffic source diversification with search engines, social media, referrals, and direct traffic
- Global visitor simulation with realistic country distribution using authentic IP ranges
-
High-volume traffic
- Configurable to produce 20,000+ visits/day
- Supports 50+ concurrent connections
-
Controlled load testing
- Auto-stop options to generate specific volumes of test data
- Perfect for running baseline vs optimized comparisons
-
Optimization workflow support
- Generate baseline data → Populate reports with realistic traffic
- Identify bottlenecks → Observe where reports slow down
- Apply optimizations → Adjust Matomo frontend/backend settings
- Validate improvements → Re-run consistent load patterns
- Docker + Docker Compose
- A running Matomo instance to test against
git clone https://github.com/Puttrix/Trafficinator.git
cd TrafficinatorThe project is fully containerized - no local Python installation needed!
For production deployments:
- Always change the default API key (
change-me-in-production) - Use HTTPS via reverse proxy (nginx, Caddy, Traefik)
- Configure CORS for specific origins
- See SECURITY.md for complete security guidelines
For production deployments with automatic updates:
- Set up GitHub Container Registry: The included GitHub Actions workflow automatically builds and pushes images to GHCR
- Deploy with auto-updates:
# Upload docker-compose.prod.yml to your remote machine docker-compose -f docker-compose.prod.yml up -d - Auto-updates: Watchtower monitors for new images every 30 seconds and automatically updates
You can paste docker-compose.prod.yml directly into a Portainer stack:
- Portainer → Stacks → Add Stack
- Paste compose content and update environment variables
- Deploy stack
No file uploads needed: Config files (including urls.txt) are now embedded directly in the Docker image during build.
See DEPLOYMENT.md for complete remote deployment instructions.
Trafficinator includes a modern web interface for easy configuration and monitoring:
# Start the Web UI and load generator
docker-compose -f docker-compose.webui.yml up -d
# Access the UI
open http://localhost:8000/uiFeatures:
- 📊 Real-time Status Dashboard - Monitor container state, uptime, and metrics
- ⚙️ Configuration Form - GUI-based config with validation and test connection
- 🎯 Load Presets - One-click Light/Medium/Heavy/Extreme scenarios
- 📋 Live Log Viewer - Real-time logs with filtering and search
- 🔒 Secure API - API key authentication and rate limiting
- 📱 Responsive Design - Works on desktop, tablet, and mobile
First-time Setup:
- Navigate to http://localhost:8000/ui
- Enter API key when prompted:
change-me-in-production - Configure your Matomo target and start generating traffic
See the complete guide: WEB_UI_GUIDE.md
For advanced users or automation, use Docker Compose directly:
# Start load generation with default settings (builds locally)
docker-compose up --build
# View logs in real-time
docker-compose logs -f matomo_loadgen
# Stop the load generator
docker-compose down# Deploy with auto-updates using GHCR image
docker-compose -f docker-compose.prod.yml up -d
# View logs
docker-compose -f docker-compose.prod.yml logs -f matomo_loadgen
# Stop
docker-compose -f docker-compose.prod.yml downEdit docker-compose.yml (development) or docker-compose.prod.yml (production) to customize your load test:
environment:
MATOMO_URL: "https://your-matomo-instance.com/matomo.php"
MATOMO_SITE_ID: "1"
MATOMO_TOKEN_AUTH: "your_api_token_here" # Required for country randomization
TARGET_VISITS_PER_DAY: "20000"
PAGEVIEWS_MIN: "3"
PAGEVIEWS_MAX: "6"
CONCURRENCY: "50"
PAUSE_BETWEEN_PVS_MIN: "0.5"
PAUSE_BETWEEN_PVS_MAX: "2.0"
AUTO_STOP_AFTER_HOURS: "24" # Stop after N hours (0 = disabled)
MAX_TOTAL_VISITS: "0" # Stop after N visits (0 = disabled)
SITESEARCH_PROBABILITY: "0.15" # Probability (0-1) that a visit includes site search
VISIT_DURATION_MIN: "1.0" # Minimum visit duration in minutes
VISIT_DURATION_MAX: "8.0" # Maximum visit duration in minutes
OUTLINKS_PROBABILITY: "0.10" # Probability (0-1) that a visit includes outlinks
DOWNLOADS_PROBABILITY: "0.08" # Probability (0-1) that a visit includes downloads
CLICK_EVENTS_PROBABILITY: "0.25" # Probability (0-1) that a visit includes click events
RANDOM_EVENTS_PROBABILITY: "0.12" # Probability (0-1) that a visit includes random events
DIRECT_TRAFFIC_PROBABILITY: "0.30" # Probability (0-1) for direct traffic (30% direct, 70% with referrers)
RANDOMIZE_VISITOR_COUNTRIES: "true" # Enable realistic country distribution (true/false)
ECOMMERCE_PROBABILITY: "0.05" # Probability (0-1) that a visit makes a purchase (5% = realistic)
ECOMMERCE_ORDER_VALUE_MIN: "15.99" # Minimum order value
ECOMMERCE_ORDER_VALUE_MAX: "299.99" # Maximum order value
ECOMMERCE_CURRENCY: "USD" # Currency code for ecommerce orders (ISO 4217)
TIMEZONE: "UTC" # Timezone for visit timestamps (e.g., "America/New_York")Use the CLI validator to confirm your environment variables (and optional Matomo connectivity) are correct before starting a load test:
python tools/validate_config.py --env-file path/to/.env
# or rely on current environment variables
python tools/validate_config.pyAdd --skip-connection to omit the connectivity probe.
Prefer the CLI? Use the ready-made presets in presets/:
# Light workload (~1k visits/day)
docker compose --env-file presets/.env.light up -d
# Medium workload (~10k visits/day)
docker compose --env-file presets/.env.medium up -d
# Heavy workload (~50k+ visits/day)
docker compose --env-file presets/.env.heavy up -dEach preset mirrors the Control UI presets; edit MATOMO_URL, MATOMO_SITE_ID, and other values as needed. See presets/README.md for details.
Trafficinator supports orchestrated conversion funnels that blend structured journeys with the existing random browsing model.
- Design funnels in the Web UI (
Funnelstab) – choose a template, tweak steps (pageviews, events, site search, outlinks, downloads, ecommerce), and save. - Sync funnels to the loader: the Control UI now writes
/app/data/funnels.jsonautomatically whenever you create, edit, or delete funnels. Prefer headless workflows? Export manually with:python tools/export_funnels.py \ --api-base http://localhost:8000 \ --api-key change-me-in-production \ --output control-ui/data/funnels.json
- Restart the generator so the loader reads the updated JSON:
docker compose -f docker-compose.webui.yml restart matomo-loadgen
The loader looks for funnels at FUNNEL_CONFIG_PATH (default /app/data/funnels.json). The default compose file mounts ./control-ui/data into both containers so exports are immediately available.
The load generator uses a 3-level hierarchical URL structure with 2,000 pre-built URLs embedded in the image:
- 10 main categories: products, blog, support, company, resources, news, services, solutions, documentation, community
- 5 subcategories each: e.g., products → hardware, software, accessories, bundles, enterprise
- 40 pages per subcategory: 2,000 total URLs for comprehensive testing
No configuration needed: URLs are built into the Docker image for immediate use.
This creates realistic navigation patterns that will generate rich data in Matomo's:
- Page hierarchy reports
- Behavior flow analysis
- Content performance metrics
- URL structure insights
The load generator includes realistic site search behavior:
- Configurable probability: Set
SITESEARCH_PROBABILITY(0.0-1.0) to control how many visits include searches - 35 realistic search terms: Including 'product', 'support', 'documentation', 'pricing', 'features', etc.
- Search categories: Random assignment to Products, Support, Documentation categories (30% probability)
- Result counts: Simulates 0-25 search results per query
- Natural placement: Search events occur randomly within visit pageviews
This generates comprehensive data for Matomo's site search analytics, helping you test and optimize search-related reports and performance.
The load generator includes realistic outlinks and download behavior:
- Outlinks (10% probability): Clicks to external websites including:
- Tech sites: GitHub, Stack Overflow, MDN, W3C
- Frameworks: React, Vue, Angular, Node.js, jQuery, Bootstrap
- Design resources: Tailwind CSS, Font Awesome, Unsplash, Google Fonts
- Social platforms: YouTube, Twitter, LinkedIn, Facebook, Instagram, Reddit, Medium
- Downloads (8% probability): File downloads including:
- Documents: PDFs (manuals, guides, whitepapers), presentations, spreadsheets
- Software: ZIP files, installers, mobile apps, source code
- Assets: Images, logos, configurations, backups
- Smart placement: Events occur randomly within visit pageviews for natural behavior
- Extended visit duration: Configurable 1-8 minute visits simulate realistic user engagement
This generates data for Matomo's Behavior → Outlinks and Behavior → Downloads reports, providing insights into user interaction with external content and file downloads.
The load generator includes realistic custom events tracking to simulate user interactions:
-
Click Events (25% probability): UI interaction events including:
- Navigation: Menu clicks, button clicks, link clicks
- UI Components: Tab clicks, accordion clicks, modal opens, image clicks
- Social: Share buttons, like buttons
- Forms: Submit actions, input focus events
- Video: Play/pause controls
- Call-to-Actions: Free trial, quote requests
-
Random Events (12% probability): Behavioral and system events including:
- Engagement: Page scrolling, time on page tracking
- Performance: Load time measurements
- Errors: 404 errors, form validation failures
- Features: Tool usage, filter/sort actions
- Content: Print, bookmark actions
- Mobile: Swipe, tap gestures
- Analytics: Conversion goals, exit intent
- User: Login/logout actions
-
Smart placement: Events occur randomly within visit pageviews (never as first action)
-
Rich metadata: Each event includes category, action, name, and optional numeric values
-
Matomo compliance: Uses proper event tracking parameters (
e_c,e_a,e_n,e_v)
This generates comprehensive data for Matomo's Behavior → Events reports, providing insights into user interactions, engagement patterns, and feature usage beyond basic pageviews.
The load generator includes realistic traffic source distribution to create diverse referrer data:
-
Search Engines (35%): Google, Bing, DuckDuckGo, Yahoo with realistic search queries like:
- "matomo analytics", "web analytics tool", "google analytics alternative"
- "privacy analytics", "gdpr compliant analytics", "open source analytics"
-
Social Media (15%): Twitter, LinkedIn, Facebook, Reddit, Hacker News, Medium, GitHub, Stack Overflow
-
Referral Sites (20%): Industry sites like:
- Software directories: AlternativeTo, Capterra, G2, SourceForge
- Marketing blogs: HubSpot, Moz, Kissmetrics, Neil Patel, Backlinko
- Tech news: TechCrunch, SearchEngineLand, MarketingLand
-
Direct Traffic (30%): Users arriving without referrers (bookmarks, direct URLs, email links)
Configuration: Adjust DIRECT_TRAFFIC_PROBABILITY (0.0-1.0) to control the direct traffic percentage. The remaining traffic is distributed among the referrer sources.
This generates realistic data for Matomo's Acquisition → All Channels and Referrers reports, helping you test and analyze traffic source performance.
The load generator includes realistic visitor country distribution using actual IP address ranges:
- United States (35%): Google, Facebook, GitHub, Cloudflare, Akamai IP ranges
- Germany (10%): Hetzner, Deutsche Telekom, T-Mobile IP ranges
- United Kingdom (8%): Microsoft Azure UK, Virgin Media, BT, Sky IP ranges
- Canada (6%): Shaw, Rogers, Bell Canada IP ranges
- France (6%): Online.net, Scaleway, Orange, France Telecom IP ranges
- Australia (5%): Telstra, Optus, TPG Australia IP ranges
- Netherlands (5%): TransIP, KPN Netherlands IP ranges
- Japan (4%): Japanese hosting and university IP ranges
- Sweden (3%): Telia, Bredband2, Comhem IP ranges
- Brazil (3%): Brazilian ISP and telecom IP ranges
- Other Countries (15%): Distributed across European, Asian, and African IP ranges
How it works: The generator uses the Matomo cip parameter to override visitor IP addresses with realistic IPs from actual ISP and hosting provider ranges for each country.
Configuration:
- Set
RANDOMIZE_VISITOR_COUNTRIES=falseto disable geolocation simulation and use your server's actual IP - Required for geolocation: You must set
MATOMO_TOKEN_AUTHwith your Matomo API token when using country randomization
Setup for Country Randomization:
- Get your Matomo API token: Go to Matomo → Personal → Security → Copy your API authentication token
- Add to your environment:
MATOMO_TOKEN_AUTH: "your_actual_api_token" RANDOMIZE_VISITOR_COUNTRIES: "true"
- Restart the container to apply changes
Note: Without the API token, Matomo will reject requests with IP overriding for security reasons, and you'll see "requires valid token_auth" errors in Matomo logs.
This creates realistic data for Matomo's Visitors → Locations reports, including country, region, and city breakdowns (depending on your GeoIP database accuracy).
The load generator supports configurable timezones for accurate visit timestamp tracking:
Default Behavior: All visits are tracked with UTC timestamps when TIMEZONE="UTC" (default)
Custom Timezone: Set any valid timezone identifier to track visits in that local time:
TIMEZONE: "America/New_York" # Eastern Time
TIMEZONE: "Europe/Stockholm" # Swedish Time
TIMEZONE: "Asia/Tokyo" # Japan Time
TIMEZONE: "Australia/Sydney" # Australian Eastern TimeHow it works: The generator uses the Matomo cdt parameter to set custom visit timestamps in the specified timezone, ensuring your analytics data reflects the correct local time for visitor activities.
Benefits:
- Accurate reporting: Visit data shows in the correct local timezone for your business
- Better insights: Understand visitor behavior patterns in your operational timezone
- Regional analysis: Match timestamp data with your local business hours and marketing campaigns
The load generator includes realistic ecommerce order tracking to simulate online purchases:
Product Catalog: 50+ products across 5 categories:
- Electronics (10 products): Smartphones, laptops, tablets, headphones, cameras, smart watches
- Clothing (10 products): T-shirts, pants, shoes, jackets, dresses, sweaters, hats
- Books (10 products): Programming guides, novels, cookbooks, textbooks, eBooks
- Home & Garden (10 products): Furniture, appliances, tools, garden supplies, decor
- Sports (10 products): Equipment, clothing, accessories, fitness trackers
Purchase Patterns:
- Order frequency: 5% of visits make a purchase by default (configurable)
- Order values: $15.99 - $299.99 range with realistic pricing variations
- Items per order: 1-5 items with weighted preference for single items (60%)
- Price calculation: Subtotal + shipping + tax = total revenue
- Order placement: Purchases occur on the final pageview (checkout completion)
Configuration Options:
ECOMMERCE_PROBABILITY: "0.05" # 5% of visits make purchases
ECOMMERCE_ORDER_VALUE_MIN: "15.99" # Minimum order value
ECOMMERCE_ORDER_VALUE_MAX: "299.99" # Maximum order value
ECOMMERCE_ITEMS_MIN: "1" # Minimum items per order
ECOMMERCE_ITEMS_MAX: "5" # Maximum items per order
ECOMMERCE_TAX_RATE: "0.10" # Tax rate (10%)
ECOMMERCE_SHIPPING_RATES: "0,5.99,9.99,15.99" # Shipping cost options
ECOMMERCE_CURRENCY: "USD" # Currency code (ISO 4217)Matomo Integration: Uses proper ecommerce tracking parameters (idgoal=0, ec_id, ec_items, revenue, ec_st, ec_tx, ec_currency) with multi-currency support to generate data for:
- Ecommerce → Orders reports
- Ecommerce → Products reports
- Ecommerce → Sales reports
- Goals → Ecommerce Orders conversion tracking
If you don't see outlinks, downloads, or custom events in Matomo, enable debug logging to see exactly what requests are being sent:
Example debug test (runs with verbose logs and stops after 50 visits):
# Add LOG_LEVEL to docker-compose.yml environment section
LOG_LEVEL: "DEBUG"
# Or run with environment override
LOG_LEVEL=DEBUG MAX_TOTAL_VISITS=50 CONCURRENCY=5 docker compose up --build --abort-on-container-exit
# Check container logs for detailed request information
docker compose logs matomo_loadgenIn the debug logs, look for these request types:
- Outlinks: Lines showing "Sending outlink hit" with
link=andurlref=parameters - Downloads: Lines showing "Sending download hit" with
download=andurlref=parameters - Custom Events: Lines showing "Sending custom event" with
e_c=,e_a=,e_n=parameters (and optionale_v=)
If events still don't appear in Matomo reports:
- Check that the events are being sent (visible in debug logs)
- Verify the Matomo server receives the requests (check server access logs)
- Ensure you're looking in the correct Matomo report sections:
- Behavior → Outlinks for external link tracking
- Behavior → Downloads for file download tracking
- Behavior → Events for custom event tracking
The load generator enforces several guarantees that help Matomo classify events correctly:
- Never first action: Outlinks, Downloads, Site Search, and Custom Events will never be the first action in a visit. A regular pageview always precedes any of these events (when the visit contains multiple pageviews).
- Proper attribution: For outlink and download hits the generator sets
urlrefto the page URL that contained the link/download. This improves Matomo's ability to attribute and display the click/download in the Outlinks/Downloads reports. - URL normalization: Download entries that are configured as relative paths are converted to fully-qualified URLs using the page's base URL before being sent to Matomo.
- Event compliance: Custom events use Matomo's standard event tracking parameters and include proper referrer information for accurate attribution.
These changes are implemented in matomo-load-baked/loader.py. Use the debug script and container logs (see above) to verify requests include the expected parameters for each event type.
MAX_TOTAL_VISITS is interpreted as a per-24-hour cap. When set to a positive integer the load generator will stop producing new visits once that daily cap is reached, then resume production when the 24-hour window resets. This allows the generator to run indefinitely while enforcing a maximum number of visits per day.
Examples:
MAX_TOTAL_VISITS=0(default) — no daily cap, generator will run indefinitely (unlessAUTO_STOP_AFTER_HOURSis set).MAX_TOTAL_VISITS=10000— generator will produce up to 10,000 visits in each rolling 24-hour window, then pause until the window resets.
You can still use AUTO_STOP_AFTER_HOURS to explicitly stop the run after a certain number of hours; if both are set, the generator will stop when either condition is met.
When the daily cap is reached the generator logs an informational message so you can detect the pause in container logs. The message looks like:
[loadgen] daily cap reached (10000). Pausing production until window reset.
Quick way to find it in container logs:
docker compose logs matomo_loadgen | grep "daily cap reached"This helps you confirm the generator paused due to the per-24-hour MAX_TOTAL_VISITS limit and not due to an error or container restart.
The load generator simulates realistic visit durations to create more accurate engagement metrics:
- Configurable duration range: Set
VISIT_DURATION_MINandVISIT_DURATION_MAXin minutes (default: 1-8 minutes) - Smart timing calculation: Total visit duration includes time spent between pageviews plus additional engagement time
- Natural behavior simulation: Users appear to stay on the site after their last pageview, simulating content consumption
- Flexible configuration examples:
- Quick browsing:
1.0-3.0minutes - Normal engagement:
2.0-8.0minutes (default:1.0-8.0) - Deep engagement:
5.0-15.0minutes
- Quick browsing:
This creates realistic session duration data in Matomo's visitor reports, helping you analyze user engagement patterns and optimize for longer visits.
Important: You must enable Site Search tracking in Matomo to see the search data generated by Trafficinator.
- Go to Administration → Websites → Manage in your Matomo dashboard
- Click the Settings button for your website
- Scroll down to the Site Search section
- Change the dropdown from "Do not track Site Search" to "Site Search tracking enabled"
Choose one of these options:
Option A (Recommended): Use default parameters
- Check the box for "Use default Site Search parameters"
- Matomo includes
searchin the default parameters
Option B: Custom parameters
- Leave the checkbox unchecked
- In the "Query parameter" field, enter:
search - In the "Category parameter" field, enter:
search_cat
- Click Save to apply the changes
- After running Trafficinator, view site search data in:
- Behavior → Site Search → Search Keywords
- Behavior → Site Search → Search Categories
- Behavior → Site Search → No Result Keywords
Note: Search events won't appear as regular pageviews - they'll show up specifically in Site Search reports.
-
Configure your Matomo instance
# Edit docker-compose.yml MATOMO_URL: "https://your-matomo-instance.com/matomo.php" MATOMO_SITE_ID: "1"
-
Enable Site Search in Matomo (if using site search feature)
- Follow the Matomo Site Search Configuration steps above
- This is required to see search data in reports
-
Generate baseline traffic data
docker-compose up --build
-
Monitor and analyze
- Check Matomo reports for performance bottlenecks
- Identify slow-loading reports (Pages, Visitors, Behavior Flow, Site Search, Outlinks, Downloads, Events, Ecommerce)
- Note database query performance and frontend rendering times
- Review comprehensive analytics: site search, outlinks, downloads, custom events, ecommerce orders, session duration, engagement metrics, traffic sources, and geolocation data
-
Optimize Matomo settings
- Tune archiving processes
- Optimize database indexing
- Adjust caching configuration
- Configure report segmentation limits
- Optimize GeoIP lookups for location reports
-
Validate improvements
# Run consistent load test to compare performance docker-compose up
Pull requests and issue reports are welcome!
If you’d like to add new traffic patterns, extend report dimensions, or improve scaling, feel free to contribute.
- WEB_UI_GUIDE.md - Complete Web UI user guide with API reference
- SECURITY.md - Security best practices for production deployment
- DEPLOYMENT.md - Remote deployment and auto-update instructions
- BACKLOG.md - Development roadmap and planned features
The Web UI exposes a REST API for programmatic control:
# Get container status
curl -H "X-API-Key: your-key" http://localhost:8000/api/status
# Start load generation
curl -X POST -H "X-API-Key: your-key" http://localhost:8000/api/start
# Stop load generation
curl -X POST -H "X-API-Key: your-key" http://localhost:8000/api/stop
# Get logs
curl -H "X-API-Key: your-key" "http://localhost:8000/api/logs?lines=100"
# Validate configuration
curl -X POST -H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{"matomo_url":"https://analytics.example.com/matomo.php","matomo_site_id":1}' \
http://localhost:8000/api/validateInteractive API Documentation: http://localhost:8000/docs
Rate Limits: 10-60 requests/minute per endpoint (configurable)
See WEB_UI_GUIDE.md for complete API documentation.
See BACKLOG.md for upcoming ideas and planned features. Recent additions include:
- ✅ Web Control UI - Complete with status dashboard, config form, presets, and logs
- ✅ REST API - Full programmatic control with authentication
- ✅ Load Presets - Light/Medium/Heavy/Extreme scenarios
- 🔄 Configuration Persistence - SQLite database for saved configs (planned)
MIT License – free to use, modify, and share.
Developed by Putte Arvfors