 #  Server-Timing for GeoIP Data Delivery to Achieve GDPR Compliance 

 

  ![Server-Timing for GeoIP Data Delivery to Achieve GDPR Compliance](https://cdn.richeyweb.com/images/articles/geoip-coming-soon/geoip-coming-soon.webp)    Delivering [GeoIP](/white-hat-seo/technical-seo "Technical SEO") data for [GDPR](/blog/development/gpc-dnt-do-not-tracks-toothless-twin "GPC: DNT/Do Not Track’s Toothless Twin") and [EU e-Privacy Directive](/blog/personal/joomla-community-magazine-mention "Joomla Community Magazine Mention!") compliance without sacrificing website [performance](/blog/hosting/mastering-the-html-head-in-joomla "Mastering the HTML head in Joomla") is a significant challenge. Server-side GeoIP lookups can disrupt [caching](/blog/development/i-built-this-on-february-3rd-cloudflare-announced-it-on-february-12th "I Built This on February 3rd. Cloudflare Announced It on February 12th") systems like [Varnish](/blog/hosting/varnish-and-joomla "Varnish and Joomla"), while client-side solutions are slow or unreliable. This article introduces a groundbreaking discovery: using the Server-Timing header to deliver GeoIP data post-caching, enabling compliance and personalization while preserving speed. This server-side solution, implemented with [nginx](/blog/hosting/tracking-ai-crawlers-with-nginx-and-google-analytics-4 "Tracking AI Crawlers with NGINX and Google Analytics 4") and Varnish, is the first step toward updating the [System - EU e-Privacy Directive](/software/joomla/plugins/system-eu-e-privacy-directive) Joomla extension to display [cookie consent](/blog/development/gdpr-is-getting-a-facelift-and-im-not-crying-over-it "GDPR is Getting a Facelift - And I’m Not Crying Over It") banners only for [EU visitors](/blog/development/new-geoip-coming-soon "New GeoIP Coming Soon"). Beyond GDPR, it supports broader GeoIP applications (e.g., city, state, continent) for content personalization, [analytics](/blog/personal/someone-elses-code "Someone Else’s Code"), and more, all while maintaining cache performance.

## The Challenge: GeoIP Delivery vs. Performance

GDPR and the e-Privacy Directive require websites to show cookie consent notices to EU visitors, necessitating accurate location detection. However, caching systems like Varnish serve pre-rendered pages, bypassing dynamic server-side GeoIP lookups. Without location data, sites risk non-compliance or degraded user experience by showing notices to non-EU users. Client-side GeoIP APIs add latency and can be blocked, and browser hints like Sec-CH-Geo-Location are untrustworthy due to spoofing or disabled settings. The goal is to deliver GeoIP data to the client without compromising caching efficiency.

## Server-Timing for Post-Cache GeoIP Delivery

The solution leverages the Server-Timing header, uniquely accessible to [JavaScript](/test-article "Shader BG Test") via the Performance API, to deliver GeoIP data after Varnish caching. This approach, discovered as a scalable way to balance compliance and performance, involves:

1. **Varnish Caching**: Varnish processes requests and serves cached responses based on backend headers (e.g., Cache-Control), unaware of GeoIP data to maximize cache hit rates.
2. **Nginx GeoIP Lookup**: After Varnish returns the response (cached or backend), the nginx load balancer performs a GeoIP lookup using a database like [MaxMind GeoLite2](https://dev.maxmind.com/geoip/geolite2-free-geolocation-data/) to determine location details (country, city, state, continent).
3. **Server-Timing Injection**: Nginx injects GeoIP data into the Server-Timing header using the more\_set\_headers module. Example: Server-Timing: geo\_country\_code;desc=US,geo\_city;desc="New York",geo\_state;desc=NY,geo\_continent;desc=NA.
4. **Client-Side Potential**: JavaScript can parse Server-Timing to enable GDPR-compliant notices or other features like content personalization, with future integration planned for the [System - EU e-Privacy Directive](/blog/personal/the-joomla-i-knew-was-free "The Joomla I Knew was Free") [Joomla](/blog/hosting/cron-vs-joomla-lazy-scheduler-and-webcron "Cron vs Joomla Lazy Scheduler and WebCron") extension.
 
This discovery ensures:

- **Performance**: Varnish caching remains intact, with no GeoIP-based cache variations, achieving response times of &lt;10ms for cache hits.
- **Flexibility**: Server-side GeoIP ensures reliable data, and Server-Timing enables client-side applications like GDPR compliance and personalization.
 
### What Does it Look Like?

It's running on this server right now. Here's what we know about you from your connection using data injected into a cached response:

This isn't ALL of the available data, it's only a few items I'm playing with.

## Broader Applications of GeoIP Data

Beyond GDPR/e-Privacy compliance, delivering GeoIP data (country, city, state, continent) via Server-Timing opens up numerous possibilities without affecting caching:

- **Content Personalization**: Display city-specific content, like "Events in New York" for geo\_city="New York", or state-specific offers.
- **Regional Customization**: Set default currencies (e.g., USD for geo\_continent=NA) or language preferences based on continent, all via client-side JavaScript.
- **Analytics**: Track anonymized visitor trends by continent or city for marketing insights, without server-side overhead.
- **[A/B Testing](/blog/development/windownamestore-a-privacy-friendly-volatile-storage-solution-for-web-developers "WindowNameStore: A Privacy-Friendly Volatile Storage Solution for Web Developers")**: Segment experiments by region (e.g., state or continent) to target user groups, keeping logic client-side to preserve caching.
- **Security**: Flag unexpected location patterns (e.g., logins from distant cities) client-side, without impacting performance.
 
These applications leverage Server-Timing’s JavaScript accessibility, maintaining Varnish’s single-cache efficiency. For server-side needs, optional cache variations (e.g., Vary: X-Geo-Continent) can be added, but this reduces hit rates and should be used sparingly.

## Server-Side Implementation

This solution is implemented server-side with nginx and Varnish, forming the foundation for future client-side integration (e.g., in the System - EU e-Privacy Directive Joomla extension). Below are the setup instructions:

### Nginx Configuration

Nginx performs GeoIP lookups post-Varnish and injects location data into Server-Timing:

 ```nginx
load_module /usr/lib/nginx/modules/ngx_http_headers_more_filter_module.so; # Enable more_set_headers
geoip_country /usr/share/GeoIP/GeoLite2-Country.mmdb { /* variable mapping occurs here */ }
geoip_city /usr/share/GeoIP/GeoLite2-City.mmdb { /* variable mapping occurs here */ }
http {
  server {
    location / {
      proxy_pass http://varnish;
      more_set_headers 'Server-Timing: geo_country_code;desc=$geoip_country_code,geo_city;desc=\"$geoip_city\",geo_state;desc=$geoip_region,geo_continent;desc=$geoip_continent_code';
    }
  }
}
```

- **GeoIP Database**: Install MaxMind GeoLite2 (ASN, Country and City editions).
- **Post-Varnish Injection**: more\_set\_headers adds Server-Timing after Varnish serves the response, preserving caching.
- **Performance**: In-memory MMDB lookups add ~1–5ms, negligible for cached responses.
- **Dependencies**: Ensure ngx\_http\_geoip2\_module and ngx\_http\_headers\_more\_filter\_module are installed:
    
     ```bash
    # Example for Ubuntu/Debian
    apt-get install libnginx-mod-http-geoip2 nginx-extras
    ```
 
### Varnish Configuration

Varnish caches pages without interacting with GeoIP or Server-Timing.

- **No Cache Variation**: Caching is independent of GeoIP, maximizing hit rates (90–99%).
- **Setup**: There is no Varnish specific configuration to be done.
 
### Future Joomla Integration

The System - EU e-Privacy Directive extension will be updated to parse Server-Timing for GDPR compliance, checking geo\_country\_code against EU/EEA country codes (e.g., AT, BE, DE).

## Handling Edge Cases

- **GeoIP Accuracy**: Daily GeoIP database updates and a default EU country code (DE) for unknown locations minimize false negatives for GDPR.
- **EU-Targeted Content**: Force EU country codes for EU-specific pages:
    
     ```nginx
    if ($request_uri ~ "/eu-shop") {
      more_set_heades 'Server-Timing: geo_country_code;desc=DE';
    }
    ```
- **[Ad Blockers](/blog/development/ad-block-detection-for-joomla-updated "Ad Block Detection for Joomla Updated")**: Default HTML banners ensure GDPR compliance if Server-Timing or JavaScript is blocked.
- **Audit Trail**: Log country codes anonymously for compliance:
    
     ```nginx
    log_format gdpr_log '$time_local - $geoip_country_code';
    access_log /var/log/nginx/gdpr.log gdpr_log;
    ```
- **GeoIP Breadth**: City/state data may be less accurate (e.g., due to VPNs); use continent-level fallbacks for robust personalization.
 
## Performance Benefits

- **Cache Hit Rates**: Varnish’s single-cache approach achieves 90–99% hit rates, with cached responses served in &lt;10ms.
- **GeoIP Overhead**: Nginx lookups add ~1–5ms post-caching, negligible compared to uncached logic (50–200ms).
- **Client-Side Efficiency**: Server-Timing parsing is &lt;1ms, with no client-side GeoIP calls.
 
## Compliance and Flexibility Benefits

- **Reliable GeoIP**: Server-side nginx lookups ensure trustworthy data, avoiding client-side vulnerabilities.
- **GDPR/e-Privacy Ready**: The foundation supports future Joomla integration for EU-targeted cookie banners.
- **Extensibility**: City, state, and continent data enable personalization, analytics, and more, all client-side.
 
## Dang - Server-Timing to the Rescue

The discovery of using Server-Timing to deliver GeoIP data post-caching is a breakthrough for GDPR/e-Privacy compliance and beyond. By implementing GeoIP lookups in nginx after Varnish caching, this solution ensures performance (sub-10ms responses) and flexibility for Joomla sites and other platforms. The System - EU e-Privacy Directive extension will soon leverage this for EU-specific cookie banners, while city, state, and continent data open doors to personalization and analytics. This scalable, compliant, and performant approach empowers developers to enhance user experiences without sacrificing speed.



- [      email ](mailto:?subject=Server-Timing+for+GeoIP+Data+Delivery+to+Achieve+GDPR+Compliance&body=https%3A%2F%2Fwww.richeyweb.com%2Fblog%2Fdevelopment%2Fserver-timing-for-geoip-data-delivery-to-achieve-gdpr-compliance)
- [      facebook ](https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fwww.richeyweb.com%2Fblog%2Fdevelopment%2Fserver-timing-for-geoip-data-delivery-to-achieve-gdpr-compliance)
- [      x-twitter ](https://twitter.com/intent/tweet?text=Server-Timing+for+GeoIP+Data+Delivery+to+Achieve+GDPR+Compliance%3A+https%3A%2F%2Fwww.richeyweb.com%2Fblog%2Fdevelopment%2Fserver-timing-for-geoip-data-delivery-to-achieve-gdpr-compliance)
- [      linkedin ](http://www.linkedin.com/shareArticle?mini=true&url=https%3A%2F%2Fwww.richeyweb.com%2Fblog%2Fdevelopment%2Fserver-timing-for-geoip-data-delivery-to-achieve-gdpr-compliance&title=Server-Timing+for+GeoIP+Data+Delivery+to+Achieve+GDPR+Compliance&summary=Delivering+GeoIP+data+for+GDPR+and+EU+e-Privacy+Di...)
- [      pinterest ](http://pinterest.com/pin/create/button/?url=https%3A%2F%2Fwww.richeyweb.com%2Fblog%2Fdevelopment%2Fserver-timing-for-geoip-data-delivery-to-achieve-gdpr-compliance&media=https%3A%2F%2Fcdn.joomla.org%2Fimages%2Fjoomla-org-og.jpg&description=Server-Timing+for+GeoIP+Data+Delivery+to+Achieve+GDPR+Compliance)
 


 

   [  Previous article: X Autopost: Player Cards   X Autopost: Player Cards ](/blog/development/x-autopost-using-the-player-card) [  Next article: Problems Turn Into Features  Problems Turn Into Features  ](/blog/development/problems-turn-into-features)  

##### We Value Your Privacy

 

We use cookies to enhance your experience and for traffic analysis. By continuing to visit this site you agree to our use of cookies.

[Privacy Policy](/privacy-policy)

 Details 

###### Google Tag Manager Items

- Ad Storage
- Ad User Data
- Ad Personalization
- Analytics Storage
- Functionality Storage
- Personalization Storage
- Security Storage
 
 

 

 

 

 

 Decline Accept
```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://www.richeyweb.com/#organization","name":"RicheyWeb","url":"https://www.richeyweb.com/","logo":{"@type":"ImageObject","url":"https://www.richeyweb.com/images/logo/richeyweb.svg","contentUrl":"https://www.richeyweb.com/images/logo/richeyweb.svg","width":{"@type":"QuantitativeValue","value":38,"unitCode":"PX"},"height":{"@type":"QuantitativeValue","value":38,"unitCode":"PX"},"@id":"https://www.richeyweb.com/#logo"},"image":{"@id":"https://www.richeyweb.com/#logo"},"sameAs":["https://x.com/ComRicheyweb","https://www.facebook.com/RicheyWebDev/","https://www.youtube.com/channel/UCxnVG8BwOvQRO7hVqNX7T2g","https://community.joomla.org/service-providers-directory/listings/115:richeyweb.html"],"description":"RicheyWeb is a custom software developer specializing in Joomla extensions.","ContactPoint":[{"@type":"ContactPoint","url":"https://www.richeyweb.com/contact-us","telephone":"903-873-8460","contactType":"Owner/Administrator","areaServed":["United States",{"@type":"Country","name":"United States","sameAs":["https://en.wikipedia.org/wiki/United_States","https://www.wikidata.org/wiki/Q30","https://g.co/kg/m/09c7w0"]},"European Union",{"@type":"AdministrativeArea","name":"European Union","sameAs":["https://en.wikipedia.org/wiki/European_Union","https://www.wikidata.org/wiki/Q458","https://g.co/kg/m/0_6t_z8"]},"United Kingdom",{"@type":"Country","name":"United Kingdom","sameAs":["https://en.wikipedia.org/wiki/United_Kingdom","https://www.wikidata.org/wiki/Q145","https://g.co/kg/m/07ssc"]},"Australia",{"@type":"Country","name":"Australia","sameAs":["https://en.wikipedia.org/wiki/Australia","https://www.wikidata.org/wiki/Q408","https://g.co/kg/m/0chghy"]},"Canada",{"@type":"Country","name":"Canada","sameAs":["https://en.wikipedia.org/wiki/Canada","https://www.wikidata.org/wiki/Q16","https://g.co/kg/m/0d060g"]},"Russia",{"@type":"Country","name":"Russia","sameAs":["https://en.wikipedia.org/wiki/Russia","https://www.wikidata.org/wiki/Q159","https://g.co/kg/m/06bnz"]},"China",{"@type":"Country","name":"China","sameAs":["https://en.wikipedia.org/wiki/China","https://www.wikidata.org/wiki/Q148","https://g.co/kg/m/0d05w3"]}],"availableLanguage":"en"},{"@type":"ContactPoint","url":"https://www.richeyweb.com/bugs","telephone":"903-873-8460","contactType":"Technical Support","areaServed":["United States",{"@type":"Country","name":"United States","sameAs":["https://en.wikipedia.org/wiki/United_States","https://www.wikidata.org/wiki/Q30","https://g.co/kg/m/09c7w0"]},"European Union",{"@type":"AdministrativeArea","name":"European Union","sameAs":["https://en.wikipedia.org/wiki/European_Union","https://www.wikidata.org/wiki/Q458","https://g.co/kg/m/0_6t_z8"]},"United Kingdom",{"@type":"Country","name":"United Kingdom","sameAs":["https://en.wikipedia.org/wiki/United_Kingdom","https://www.wikidata.org/wiki/Q145","https://g.co/kg/m/07ssc"]},"Australia",{"@type":"Country","name":"Australia","sameAs":["https://en.wikipedia.org/wiki/Australia","https://www.wikidata.org/wiki/Q408","https://g.co/kg/m/0chghy"]},"Canada",{"@type":"Country","name":"Canada","sameAs":["https://en.wikipedia.org/wiki/Canada","https://www.wikidata.org/wiki/Q16","https://g.co/kg/m/0d060g"]},"Russia",{"@type":"Country","name":"Russia","sameAs":["https://en.wikipedia.org/wiki/Russia","https://www.wikidata.org/wiki/Q159","https://g.co/kg/m/06bnz"]},"China",{"@type":"Country","name":"China","sameAs":["https://en.wikipedia.org/wiki/China","https://www.wikidata.org/wiki/Q148","https://g.co/kg/m/0d05w3"]}],"availableLanguage":"en"}],"knowsAbout":["Computer programming",{"@type":"Thing","name":"Computer programming","sameAs":["https://en.wikipedia.org/wiki/Computer_programming","https://www.wikidata.org/wiki/Q80006","https://g.co/kg/m/01mf_"]},"PHP",{"@type":"Thing","name":"PHP","sameAs":["https://en.wikipedia.org/wiki/PHP","https://www.wikidata.org/wiki/Q59","https://g.co/kg/m/060kv"]},"JavaScript",{"@type":"Thing","name":"JavaScript","sameAs":["https://en.wikipedia.org/wiki/JavaScript","https://www.wikidata.org/wiki/Q2005","https://g.co/kg/m/02p97"]},"arduino","Computer forensics",{"@type":"Thing","name":"Computer forensics","sameAs":["https://en.wikipedia.org/wiki/Computer_forensics","https://www.wikidata.org/wiki/Q878553","https://g.co/kg/m/02wxbd"]},"White hat",{"@type":"Thing","name":"White hat","sameAs":["https://en.wikipedia.org/wiki/White_hat_(computer_security)","https://www.wikidata.org/wiki/Q7995625","https://g.co/kg/m/03ns_5"]},"Search engine optimization",{"@type":"Thing","name":"Search engine optimization","sameAs":["https://en.wikipedia.org/wiki/Search_engine_optimization","https://www.wikidata.org/wiki/Q180711","https://g.co/kg/m/019qb_"]},"Search engine marketing",{"@type":"Thing","name":"Search engine marketing","sameAs":["https://en.wikipedia.org/wiki/Search_engine_marketing","https://www.wikidata.org/wiki/Q846132","https://g.co/kg/m/06mw8r"]},"Digital marketing",{"@type":"Thing","name":"Digital marketing","sameAs":["https://en.wikipedia.org/wiki/Digital_marketing","https://www.wikidata.org/wiki/Q1323528","https://g.co/kg/g/122hcnps"]},"Web hosting service",{"@type":"Thing","name":"Web hosting service","sameAs":["https://en.wikipedia.org/wiki/Web_hosting_service","https://www.wikidata.org/wiki/Q5892272","https://g.co/kg/m/014pz4"]},"Email hosting service",{"@type":"Thing","name":"Email hosting service","sameAs":["https://en.wikipedia.org/wiki/Email_hosting_service","https://www.wikidata.org/wiki/Q5368818","https://g.co/kg/m/09w60m"]},"Internet hosting service",{"@type":"Thing","name":"Internet hosting service","sameAs":["https://en.wikipedia.org/wiki/Internet_hosting_service","https://www.wikidata.org/wiki/Q1210425","https://g.co/kg/m/09w5yw"]},"Virtual hosting",{"@type":"Thing","name":"Virtual hosting","sameAs":["https://en.wikipedia.org/wiki/Virtual_hosting","https://www.wikidata.org/wiki/Q588365","https://g.co/kg/m/024mvh"]},"Web performance",{"@type":"Thing","name":"Web performance","sameAs":["https://en.wikipedia.org/wiki/Web_performance","https://www.wikidata.org/wiki/Q7978612","https://g.co/kg/m/0gfj3f1"]},"Web content management system",{"@type":"Thing","name":"Web content management system","sameAs":["https://en.wikipedia.org/wiki/Web_content_management_system","https://www.wikidata.org/wiki/Q45211","https://g.co/kg/m/0615s2"]},"Content management system",{"@type":"Thing","name":"Content management system","sameAs":["https://en.wikipedia.org/wiki/Content_management_system","https://www.wikidata.org/wiki/Q131093","https://g.co/kg/m/0k23c"]},"General Data Protection Regulation",{"@type":"Thing","name":"General Data Protection Regulation","sameAs":["https://en.wikipedia.org/wiki/General_Data_Protection_Regulation","https://www.wikidata.org/wiki/Q1172506","https://g.co/kg/m/0pk_7xs"]},"SERP",{"@type":"Thing","name":"SERP","sameAs":["https://en.wikipedia.org/wiki/SERP","https://www.wikidata.org/wiki/Q2205811","https://g.co/kg/g/11c5szp7kc"]},"Artificial intelligence",{"@type":"Thing","name":"Artificial intelligence","sameAs":["https://en.wikipedia.org/wiki/Artificial_intelligence","https://www.wikidata.org/wiki/Q11660","https://g.co/kg/m/0mkz"]},"Prompt engineering",{"@type":"Thing","name":"Prompt engineering","sameAs":["https://en.wikipedia.org/wiki/Prompt_engineering","https://www.wikidata.org/wiki/Q108941486","https://g.co/kg/g/11p6kpgt_n"]},"E-learning",{"@type":"Thing","name":"E-learning","sameAs":["https://en.wikipedia.org/wiki/E-learning_(theory)","https://www.wikidata.org/wiki/Q182250","https://g.co/kg/g/122czm1f"]},"Sharable Content Object Reference Model",{"@type":"Thing","name":"Sharable Content Object Reference Model","sameAs":["https://en.wikipedia.org/wiki/Sharable_Content_Object_Reference_Model","https://www.wikidata.org/wiki/Q827811","https://g.co/kg/m/06_40"]},"Experience API",{"@type":"Thing","name":"Experience API","sameAs":["https://en.wikipedia.org/wiki/Experience_API","https://www.wikidata.org/wiki/Q7807728","https://g.co/kg/g/1yw9ktxr8"]},"Joomla",{"@type":"Thing","name":"Joomla","sameAs":["https://en.wikipedia.org/wiki/Joomla","https://www.wikidata.org/wiki/Q13167","https://g.co/kg/m/07qb81"]},"Nginx",{"@type":"Thing","name":"Nginx","sameAs":["https://en.wikipedia.org/wiki/Nginx","https://www.wikidata.org/wiki/Q306144","https://g.co/kg/m/02qft91"]},"MySQL",{"@type":"Thing","name":"MySQL","sameAs":["https://en.wikipedia.org/wiki/MySQL","https://www.wikidata.org/wiki/Q850","https://g.co/kg/m/04y3k"]}],"areaServed":["United States",{"@type":"Country","name":"United States","sameAs":["https://en.wikipedia.org/wiki/United_States","https://www.wikidata.org/wiki/Q30","https://g.co/kg/m/09c7w0"]},"European Union",{"@type":"AdministrativeArea","name":"European Union","sameAs":["https://en.wikipedia.org/wiki/European_Union","https://www.wikidata.org/wiki/Q458","https://g.co/kg/m/0_6t_z8"]},"United Kingdom",{"@type":"Country","name":"United Kingdom","sameAs":["https://en.wikipedia.org/wiki/United_Kingdom","https://www.wikidata.org/wiki/Q145","https://g.co/kg/m/07ssc"]},"Australia",{"@type":"Country","name":"Australia","sameAs":["https://en.wikipedia.org/wiki/Australia","https://www.wikidata.org/wiki/Q408","https://g.co/kg/m/0chghy"]},"Canada",{"@type":"Country","name":"Canada","sameAs":["https://en.wikipedia.org/wiki/Canada","https://www.wikidata.org/wiki/Q16","https://g.co/kg/m/0d060g"]},"Russia",{"@type":"Country","name":"Russia","sameAs":["https://en.wikipedia.org/wiki/Russia","https://www.wikidata.org/wiki/Q159","https://g.co/kg/m/06bnz"]},"China",{"@type":"Country","name":"China","sameAs":["https://en.wikipedia.org/wiki/China","https://www.wikidata.org/wiki/Q148","https://g.co/kg/m/0d05w3"]}],"memberOf":["Mensa International",{"@type":"Organization","name":"Mensa International","sameAs":["https://en.wikipedia.org/wiki/Mensa_International","https://www.wikidata.org/wiki/Q184194","https://g.co/kg/m/0140pf"]},"National Rifle Association",{"@type":"Organization","name":"National Rifle Association","sameAs":["https://en.wikipedia.org/wiki/National_Rifle_Association","https://www.wikidata.org/wiki/Q863259","https://g.co/kg/m/0j6f9"]},"CompTIA",{"@type":"Organization","name":"CompTIA","sameAs":["https://en.wikipedia.org/wiki/CompTIA","https://www.wikidata.org/wiki/Q597534","https://g.co/kg/m/040shq"]},"ISFCE LLC",{"@type":"Organization","name":"ISFCE LLC","sameAs":["https://isfce.com","https://g.co/kg/g/11wxm5r0rg"]}],"hasCredential":[{"@type":"EducationalOccupationalCredential","name":"Joomla 3 Certified Administrator","credentialCategory":"Certification","description":"Administrator Exam is the first available Joomla! certification exam","recognizedBy":{"@type":"Organization","name":"Open Source Matters, Inc.","sameAs":["https://en.wikipedia.org/wiki/Open_Source_Matters,_Inc.","https://g.co/kg/g/11f00wvjhz"]},"url":"https://certification.joomla.org/certified-user-directory/michael-richey","about":["Content management system",{"@type":"Thing","name":"Content management system","sameAs":["https://en.wikipedia.org/wiki/Content_management_system","https://www.wikidata.org/wiki/Q131093","https://g.co/kg/m/0k23c"]},"Web content management system",{"@type":"Thing","name":"Web content management system","sameAs":["https://en.wikipedia.org/wiki/Web_content_management_system","https://www.wikidata.org/wiki/Q45211","https://g.co/kg/m/0615s2"]},"Joomla",{"@type":"Thing","name":"Joomla","sameAs":["https://en.wikipedia.org/wiki/Joomla","https://www.wikidata.org/wiki/Q13167","https://g.co/kg/m/07qb81"]}],"educationalLevel":"expert","image":{"@type":"ImageObject","url":"https://www.richeyweb.com/images/contact/badge.webp","contentUrl":"https://www.richeyweb.com/images/contact/badge.webp","width":{"@type":"QuantitativeValue","value":300,"unitCode":"PX"},"height":{"@type":"QuantitativeValue","value":86,"unitCode":"PX"},"caption":"Joomla 3 Certified Administrator"}},{"@type":"EducationalOccupationalCredential","name":"Certified Computer Examiner","credentialCategory":"Certification","description":"Internationally recognized computer forensics certifiecation","recognizedBy":{"@type":"Organization","name":"ISFCE LLC","sameAs":["https://en.wikipedia.org/wiki/ISFCE_LLC","https://g.co/kg/g/11wxm5r0rg"]},"url":"https://isfce.com/","about":["Digital forensics",{"@type":"Thing","name":"Digital forensics","sameAs":["https://en.wikipedia.org/wiki/Digital_forensics","https://www.wikidata.org/wiki/Q3246940","https://g.co/kg/m/0cnxzfx"]},"Computer forensics",{"@type":"Thing","name":"Computer forensics","sameAs":["https://en.wikipedia.org/wiki/Computer_forensics","https://www.wikidata.org/wiki/Q878553","https://g.co/kg/m/02wxbd"]},"Mobile device forensics",{"@type":"Thing","name":"Mobile device forensics","sameAs":["https://en.wikipedia.org/wiki/Mobile_device_forensics","https://www.wikidata.org/wiki/Q6887097","https://g.co/kg/m/06zp3tp"]},"Network forensics",{"@type":"Thing","name":"Network forensics","sameAs":["https://en.wikipedia.org/wiki/Network_forensics","https://www.wikidata.org/wiki/Q7001032","https://g.co/kg/m/05pb280"]},"Database forensics",{"@type":"Thing","name":"Database forensics","sameAs":["https://en.wikipedia.org/wiki/Database_forensics","https://www.wikidata.org/wiki/Q5227405","https://g.co/kg/m/0cgqsy"]}],"educationalLevel":"expert","image":{"@type":"ImageObject","url":"https://www.richeyweb.com/images/contact/isfce-cce.webp","contentUrl":"https://www.richeyweb.com/images/contact/isfce-cce.webp","width":{"@type":"QuantitativeValue","value":150,"unitCode":"PX"},"height":{"@type":"QuantitativeValue","value":150,"unitCode":"PX"},"caption":"Certified Computer Examiner"}}],"hasOfferCatalog":{"@type":"OfferCatalog","name":"Web Services","itemListElement":[{"@type":"Offer","itemOffered":{"@type":"Service","name":"Hosting"}},{"@type":"Offer","itemOffered":{"@type":"Service","name":"Development"}},{"@type":"Offer","itemOffered":{"@type":"Service","name":"Search Engine Optimization"}}]}},{"@type":"WebSite","@id":"https://www.richeyweb.com/#website","url":"https://www.richeyweb.com/","name":"RicheyWeb","publisher":{"@id":"https://www.richeyweb.com/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://www.richeyweb.com/search?q={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string","valueMaxLength":256,"valueMinLength":2,"valuePattern":"^[A-Za-z0-9\\s]+$"}},"creator":{"@id":"https://www.richeyweb.com/#organization"},"copyrightHolder":{"@id":"https://www.richeyweb.com/#organization"}},{"@type":"WebPage","@id":"https://www.richeyweb.com/blog/development/server-timing-for-geoip-data-delivery-to-achieve-gdpr-compliance#webpage","url":"https://www.richeyweb.com/blog/development/server-timing-for-geoip-data-delivery-to-achieve-gdpr-compliance","name":"Server-Timing for GeoIP Data Delivery to Achieve GDPR Compliance","description":"Achieve GDPR and EU e-Privacy compliance without sacrificing performance using Server-Timing to deliver GeoIP data post-caching.","isPartOf":{"@id":"https://www.richeyweb.com/#website"},"about":{"@id":"https://www.richeyweb.com/#organization"},"inLanguage":"en-GB"},{"@type":"Article","image":{"@type":"ImageObject","url":"https://www.richeyweb.com/images/articles/geoip-coming-soon/geoip-coming-soon.webp","contentUrl":"https://www.richeyweb.com/images/articles/geoip-coming-soon/geoip-coming-soon.webp","width":{"@type":"QuantitativeValue","value":508,"unitCode":"PX"},"height":{"@type":"QuantitativeValue","value":285,"unitCode":"PX"},"caption":"Server-Timing for GeoIP Data Delivery to Achieve GDPR Compliance","representativeOfPage":true},"headline":"Server-Timing for GeoIP Data Delivery to Achieve GDPR Compliance","description":"Achieve GDPR and EU e-Privacy compliance without sacrificing performance using Server-Timing to deliver GeoIP data post-caching.","author":{"@type":"Person","name":"Michael Richey","url":"https://www.richeyweb.com/contact-us","@id":"https://www.richeyweb.com/contact-us#person"},"datePublished":"2025-09-17T00:00:00+00:00","dateModified":"2026-03-30T00:00:00+00:00","about":["General Data Protection Regulation",{"@type":"Thing","name":"General Data Protection Regulation","sameAs":["https://en.wikipedia.org/wiki/General_Data_Protection_Regulation","https://www.wikidata.org/wiki/Q1172506","https://g.co/kg/m/0pk_7xs"]},"HTTP header injection",{"@type":"Thing","name":"HTTP header injection","sameAs":["https://en.wikipedia.org/wiki/HTTP_header_injection","https://www.wikidata.org/wiki/Q1592277","https://g.co/kg/m/0264984"]},"Header",{"@type":"Thing","name":"Header","sameAs":["https://en.wikipedia.org/wiki/Header_(computing)","https://www.wikidata.org/wiki/Q747318","https://g.co/kg/m/02dnj_"]},"HTTP",{"@type":"Thing","name":"HTTP","sameAs":["https://en.wikipedia.org/wiki/HTTP","https://www.wikidata.org/wiki/Q8777","https://g.co/kg/m/03hgt"]},"Server-Timing","ePrivacy Directive",{"@type":"Book","name":"ePrivacy Directive","sameAs":["https://en.wikipedia.org/wiki/EPrivacy_Directive","https://www.wikidata.org/wiki/Q1744072","https://g.co/kg/m/02qv74_"]},"Joomla",{"@type":"Thing","name":"Joomla","sameAs":["https://en.wikipedia.org/wiki/Joomla","https://www.wikidata.org/wiki/Q13167","https://g.co/kg/m/07qb81"]}],"mentions":["content personalization (web strategy)","Varnish",{"@type":"Thing","name":"Varnish","sameAs":["https://en.wikipedia.org/wiki/Varnish_(software)","https://www.wikidata.org/wiki/Q81683","https://g.co/kg/m/0279z4k"]},"Nginx",{"@type":"Thing","name":"Nginx","sameAs":["https://en.wikipedia.org/wiki/Nginx","https://www.wikidata.org/wiki/Q306144","https://g.co/kg/m/02qft91"]},"MaxMind",{"@type":"Organization","name":"MaxMind","sameAs":["https://en.wikipedia.org/wiki/MaxMind","https://www.wikidata.org/wiki/Q25022243","https://g.co/kg/g/11cmttz01t"]},"JavaScript",{"@type":"Thing","name":"JavaScript","sameAs":["https://en.wikipedia.org/wiki/JavaScript","https://www.wikidata.org/wiki/Q2005","https://g.co/kg/m/02p97"]},"European Union",{"@type":"AdministrativeArea","name":"European Union","sameAs":["https://en.wikipedia.org/wiki/European_Union","https://www.wikidata.org/wiki/Q458","https://g.co/kg/m/0_6t_z8"]},"Privacy policy",{"@type":"Thing","name":"Privacy policy","sameAs":["https://en.wikipedia.org/wiki/Privacy_policy","https://www.wikidata.org/wiki/Q1999831","https://g.co/kg/m/04tx6w"]},"Analytics",{"@type":"Thing","name":"Analytics","sameAs":["https://en.wikipedia.org/wiki/Analytics","https://www.wikidata.org/wiki/Q485396","https://g.co/kg/m/02gcn9"]}],"@id":"https://www.richeyweb.com/blog/development/server-timing-for-geoip-data-delivery-to-achieve-gdpr-compliance#article","isPartOf":{"@id":"https://www.richeyweb.com/blog/development/server-timing-for-geoip-data-delivery-to-achieve-gdpr-compliance#webpage"},"publisher":{"@id":"https://www.richeyweb.com/#organization"},"keywords":"GDPR, EU e-Privacy Directive, Server-Timing, GeoIP, Varnish, caching, nginx, performance, cookie consent, Joomla, System - EU e-Privacy Directive, client-side, JavaScript, Performance API, GeoIP data, country code, city, state, continent, personalization, analytics, compliance, cache hit rates, MaxMind GeoLite2, more_add_headers, EU visitors, server-side, post-caching, A/B testing, regional customization, audit trail, ad blockers, fallback","articleSection":"Development","url":"https://www.richeyweb.com/blog/development/server-timing-for-geoip-data-delivery-to-achieve-gdpr-compliance"}]}
```
