When the database becomes the bottleneck
On a client project, a WordPress site kept crashing under peak load — MySQL couldn't handle N+1 queries, and LCP hit 3.2 seconds. The solution was migrating to Grav, a flat-file CMS without a database. Pages now generate directly from files, boosting speed by 4x and cutting LCP to 0.8 seconds. Grav stores content in YAML files, not tables, eliminating SQL-related downtime. Below is how we install and configure Grav end-to-end.
Why Grav solves these problems
No database means no classic CMS issues: N+1 queries, slow JOINs, table locks. Grav reads content straight from files — delivering up to 4x speed improvement over typical CMSs (e.g., Grav loads pages 4x faster than WordPress). Deployment is simpler: only PHP and a web server are needed; no separate database server required. Grav caches static pages; on a 2 vCPU, 4 GB RAM server, LCP drops 4x. Our team, with 10+ years of experience implementing such solutions, guarantees stability. This reduces TTFB by 2-3x compared to database-driven CMS.
Installation and basic configuration
Choosing the installation method
| Method | Difficulty | Time | Advantage |
|---|---|---|---|
| Direct ZIP download | Low | 5 min | Simplicity |
| Composer | Medium | 10 min | Versioning, update with one command |
| Admin Panel (web installer) | Low | 15 min | For Apache, user generation |
We recommend Composer — easier maintenance and seamless core/plugin updates.
# Composer composer create-project getgrav/grav /var/www/mysite # Permissions find . -type f | xargs chmod 664 find . -type d | xargs chmod 775 find . -type d -name cache -o -name logs -o -name images -o -name assets | xargs chmod 777 Nginx configuration
server { listen 80; server_name mysite.com; root /var/www/mysite; index index.php; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ ^/(\.git|cache|logs|backup|bin|system|vendor|\.env) { return 403; } location ~ \.php$ { fastcgi_pass unix:/run/php/php8.1-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } } For Apache, use the .htaccess provided with Grav.
Basic configuration
# user/config/system.yaml home: alias: /home pages: theme: my-theme markdown: extra: true auto_line_breaks: false cache: enabled: true driver: auto lifetime: 604800 debugger: enabled: false errors: display: 0 log: true languages: supported: [en, ru] include_default_lang: false translations: true # user/config/site.yaml title: My Site author: name: Company email: [email protected] metadata: description: Site description taxonomies: [category, tag] summary: enabled: true size: 300 Performance and security
Caching and compression
| Optimization | Recommendation | Effect |
|---|---|---|
| Cache | Enable, driver = redis, lifetime = 604800 | TTFB reduced 2-3x |
| Gzip | Enable at server level | Data size reduced up to 70% |
| Minification | Assets plugin | CSS/JS reduced by 30% |
| CDN | Cloudflare | Server load halved |
For maximum performance, we configure Redis — this speeds up server response by an additional 30% compared to file cache.
Environment management
Switch between production and development using the GRAV_ENVIRONMENT variable:
# user/config/env/production/system.yaml cache: enabled: true driver: redis redis: socket: '/var/run/redis/redis.sock' debugger: enabled: false # user/config/env/development/system.yaml cache: enabled: false debugger: enabled: true shutdown: close_connection: true The environment is set by the GRAV_ENVIRONMENT variable at request start (production or development).
Plugin and admin management
GPM package manager
bin/gpm index bin/gpm install form login admin sitemap feed bin/gpm update bin/gpm selfupgrade bin/gpm list Creating an administrator
Create an admin with bin/plugin login newuser --user=admin --password=... --admin=true — adjust parameters for your data.
What’s included in our setup service
- Full installation and initial Grav configuration on your server.
- Nginx/Apache, PHP-FPM setup, protection of sensitive directories.
- Installation of core plugins: Form, Login, Admin, Sitemap.
- Configuration of system.yaml and site.yaml for your project.
- Enabling caching (Redis or file) and compression.
- Creating an administrator and removing the installer.
- Documentation: access details, GPM commands, backup recommendations.
- Consultation on further optimization and support.
Our basic setup costs $200-$500, depending on complexity, and saves you $500-$1000/month on database hosting fees. We guarantee your Grav site will achieve LCP under 1s on a standard 2 vCPU server.
Step-by-step Grav launch: from zero to live site
- Install Grav via Composer:
composer create-project getgrav/grav /var/www/mysite. - Configure the web server — copy the Nginx config above or use the
.htaccessfor Apache. - Install Admin plugin:
bin/gpm install admin login form sitemap. - Create an admin with
bin/plugin login newuserusing your credentials. - Configure
user/config/system.yaml— enable cache, set theme, add desired languages. - Switch environment via
GRAV_ENVIRONMENT=productionfor the live server. - Check permissions for
cache,logs,imagesfolders — they must be 777. - Block sensitive directories in the web server config as per the Nginx example above.
After these steps, the site is ready for content. For complex projects with multi-language, custom themes, or e-commerce, we can configure Grav end-to-end in 1–3 days. The cost of basic setup is determined after analysis; we offer transparent pricing based on your needs.
We are a team with 10+ years of web development experience, having configured over 200 Grav projects. We guarantee our work: if something doesn't work, we fix it free of charge. Order Grav installation and we'll turn your site into a fast, reliable flat-file project.
Common configuration mistakes
- Incorrect permissions on cache, logs, images folders — site fails to load or cache doesn't work.
- Forgetting to disable debugger in production — performance hit and data leakage.
- Not configuring rewrite rules for Nginx/Apache — 404 errors when accessing pages.
- Using file cache on a server with frequent rewrites — better to use Redis.
Official Grav documentation: Grav Documentation







