diff --git a/roles/archwiki/files/nginx-cache-purge b/roles/archwiki/files/nginx-cache-purge
new file mode 100644
index 0000000000000000000000000000000000000000..d1bc7262eeec17786617028a6cc33fd318b59d05
--- /dev/null
+++ b/roles/archwiki/files/nginx-cache-purge
@@ -0,0 +1,30 @@
+#!/usr/bin/env python
+import hashlib
+import http.server
+import pathlib
+import socketserver
+import urllib.parse
+
+socketserver.ThreadingTCPServer.allow_reuse_address = True
+
+
+class Handler(http.server.BaseHTTPRequestHandler):
+    def do_PURGE(self):
+        self.send_response(http.HTTPStatus.OK)
+        self.end_headers()
+        o = urllib.parse.urlparse(self.path)
+        for method in ["GET", "HEAD"]:
+            # Please keep in sync with "fastcgi_cache_key" in nginx.d.conf.j2
+            if o.query:
+                cache_key = f"https{method}{o.netloc}{o.path}?{o.query}"
+            else:
+                cache_key = f"https{method}{o.netloc}{o.path}"
+            hash = hashlib.md5(cache_key.encode("utf-8")).hexdigest()
+            # Please keep in sync with "fastcgi_cache_path" in nginx.d.conf.j2
+            pathlib.Path(
+                f"/var/lib/nginx/cache/{hash[-1]}/{hash[-3:-1]}/{hash}"
+            ).unlink(missing_ok=True)
+
+
+httpd = http.server.ThreadingHTTPServer(("127.0.0.1", 1080), Handler)
+httpd.serve_forever()
diff --git a/roles/archwiki/tasks/main.yml b/roles/archwiki/tasks/main.yml
index 9140317c71e77a078cf0c94e0184de3d2ae2c486..789cb15173d750726a9f03dc9d3724d79f585a8c 100644
--- a/roles/archwiki/tasks/main.yml
+++ b/roles/archwiki/tasks/main.yml
@@ -97,16 +97,18 @@
 - name: Start and enable memcached service
   systemd: name=memcached@archwiki.service state=started enabled=true daemon_reload=true
 
+- name: Install nginx-cache-purge script
+  copy: src=nginx-cache-purge dest=/usr/local/bin/nginx-cache-purge owner=root group=root mode=0755
+
 - name: Install systemd services/timers
   template: src="{{ item }}.j2" dest="/etc/systemd/system/{{ item }}" owner=root group=root mode=0644
   loop:
     - archwiki-runjobs.service
     - archwiki-runjobs-wait.service
     - archwiki-runjobs.timer
-    - archwiki-prune-cache.service
-    - archwiki-prune-cache.timer
     - archwiki-question-updater.service
     - archwiki-question-updater.timer
+    - nginx-cache-purge.service
 
 - name: Start and enable archwiki timers and services
   systemd:
@@ -116,9 +118,9 @@
     daemon_reload: true
   with_items:
     - archwiki-runjobs.timer
-    - archwiki-prune-cache.timer
     - archwiki-runjobs-wait.service
     - archwiki-question-updater.timer
+    - nginx-cache-purge.service
 
 - name: Create question answer file
   systemd:
diff --git a/roles/archwiki/templates/LocalSettings.php.j2 b/roles/archwiki/templates/LocalSettings.php.j2
index 70b55bb3dca2d28cacf895476b62fdbc615f85d0..d5b049494b144e2dcc92c4743bbdda85cfbc15f6 100644
--- a/roles/archwiki/templates/LocalSettings.php.j2
+++ b/roles/archwiki/templates/LocalSettings.php.j2
@@ -147,9 +147,9 @@ $wgMemCachedServers = [ "unix://{{ archwiki_memcached_socket }}" ];
 ## be publicly accessible from the web.
 $wgCacheDirectory = "$IP/../cache/data";
 $wgEnableSidebarCache = true;
-$wgUseFileCache = true;
-$wgFileCacheDirectory = "$IP/../cache/html";
-$wgUseGzip = true;
+$wgUseCdn = true;
+$wgCdnServers = [ '127.0.0.1' ];
+$wgInternalServer = 'http://wiki.archlinux.org';
 
 # CSS-based preferences supposedly cause about 20 times slower page loads
 # https://phabricator.wikimedia.org/rSVN63707
diff --git a/roles/archwiki/templates/archwiki-prune-cache.service.j2 b/roles/archwiki/templates/archwiki-prune-cache.service.j2
deleted file mode 100644
index 458800531d39d525f1aa6ea23bfc038b0ec3f2c4..0000000000000000000000000000000000000000
--- a/roles/archwiki/templates/archwiki-prune-cache.service.j2
+++ /dev/null
@@ -1,21 +0,0 @@
-[Unit]
-Description=Archwiki Prune Cache Service
-
-[Service]
-Type=oneshot
-User={{ archwiki_user }}
-WorkingDirectory={{ archwiki_dir }}
-ExecStart=/usr/bin/php {{ archwiki_dir }}/public/maintenance/run.php pruneFileCache -q --agedays 1
-
-NoNewPrivileges=yes
-PrivateTmp=yes
-PrivateDevices=yes
-PrivateNetwork=true
-ProtectSystem=full
-ProtectHome=true
-ProtectControlGroups=yes
-ProtectKernelModules=yes
-ProtectKernelTunables=yes
-
-[Install]
-WantedBy=multi-user.target
diff --git a/roles/archwiki/templates/archwiki-prune-cache.timer.j2 b/roles/archwiki/templates/archwiki-prune-cache.timer.j2
deleted file mode 100644
index 95200a1904d20b83e35dd4a52e9ea694387e1024..0000000000000000000000000000000000000000
--- a/roles/archwiki/templates/archwiki-prune-cache.timer.j2
+++ /dev/null
@@ -1,8 +0,0 @@
-[Unit]
-Description=Archwiki Prune Cache timer
-
-[Timer]
-OnCalendar=*-*-* 04:12:00
-
-[Install]
-WantedBy=timers.target
diff --git a/roles/archwiki/templates/nginx-cache-purge.service.j2 b/roles/archwiki/templates/nginx-cache-purge.service.j2
new file mode 100644
index 0000000000000000000000000000000000000000..a8d619fecca7cc21a1698862d1e25eb3ced755b9
--- /dev/null
+++ b/roles/archwiki/templates/nginx-cache-purge.service.j2
@@ -0,0 +1,11 @@
+[Unit]
+Description=nginx cache PURGE service
+
+[Service]
+User=http
+ProtectSystem=strict
+ReadWritePaths=/var/lib/nginx/cache
+ExecStart=/usr/local/bin/nginx-cache-purge
+
+[Install]
+WantedBy=multi-user.target
diff --git a/roles/archwiki/templates/nginx.d.conf.j2 b/roles/archwiki/templates/nginx.d.conf.j2
index 86bc74263b712fbdcbaa89f299c293eecd553399..e83eab7f95acd48d382d5d066b3978e508301967 100644
--- a/roles/archwiki/templates/nginx.d.conf.j2
+++ b/roles/archwiki/templates/nginx.d.conf.j2
@@ -1,4 +1,6 @@
-fastcgi_cache_path /var/lib/nginx/cache levels=1:2 keys_zone=wiki:100m inactive=60m;
+# Please keep "path" and "levels" in sync with nginx-cache-purge
+fastcgi_cache_path /var/lib/nginx/cache levels=1:2 keys_zone=wiki:100m inactive=720m;
+# Please keep in sync with "cache_key" in nginx-cache-purge
 fastcgi_cache_key "$scheme$request_method$host$request_uri";
 
 # rate limit API endpoint
@@ -110,10 +112,18 @@ server {
         fastcgi_index  index.php;
         include        fastcgi.conf;
 
+{% block wiki_cache %}
         fastcgi_cache wiki;
-        fastcgi_cache_valid 200 10m;
+        # This improves the cache hit ratio[1] and ensures that there is
+        # only a single cache file. Without this, nginx will use the
+        # Vary header as an secondary cache key[2], which breaks the
+        # cache purge servce.
+        # [1] https://www.fastly.com/blog/best-practices-using-vary-header/
+        # [2] https://github.com/nginx/nginx/commit/1332e76b20a6a1e871904525d42b17dcaed81eec
+        fastcgi_ignore_headers Vary;
 
         add_header X-Cache $upstream_cache_status;
+{% endblock %}
     }
 
     # mediawiki API endpoint
@@ -141,6 +151,11 @@ server {
         fastcgi_index  index.php;
         include        fastcgi.conf;
 
+{{ self.wiki_cache() }}
+        # https://www.mediawiki.org/w/index.php?title=Manual:Varnish_caching&oldid=6230975#Configuring_Varnish
+        fastcgi_cache_bypass $http_authorization $cookie_archwiki_session $cookie_archwikiToken;
+        fastcgi_no_cache $http_authorization $cookie_archwiki_session $cookie_archwikiToken;
+
         limit_req zone=archwikilimit burst=10 nodelay;
     }