WordFence creates a lot of database writes?
-
Hello,
This is really not a ‘support question’, but rather a request for some information.
As far as I can see, WordFence will write to the database each time an access is made (for the real-time activity display). Although there is a limit to the number of entries stored in the database, and on a very busy site it means that the table for the hits does not grow beyond that limit, the truth is that there will be a database write with every hit!
Because the main server I use has plenty of power for the sites it runs, I wasn’t even aware of all those database writes. But then I started doing a MySQL replication on a backup server which works as a cold stand-by in case the main one fails. Its specs are much, much lower than the main server — the point is that it ought just to keep the sites barely alive while I work on the main one, if it goes down for some reason — but, for a while, I didn’t really notice anything being wrong. Then, one day, a couple of months ago, I suddenly realised that the replication was getting hopelessly out of sync! Researching on the logs to see what was wrong, I noticed gazillions of entries on the WordFence tables for recording hits, and these were completely swamping over the poor backup server — way too many disk writes for its underpowered hardware.
So the solution seemed to be to turn off all real-time display activity on all websites I run. This slightly improved the performance of the backup server (while it also improved the main server’s performance, of course, but it was not overwhelmingly noticeable, since, as said, the main one has plenty of CPU cycles and I/O, as well as lots of free RAM), but I still got a lot of writes for the hits table.
Now this might just be a coincidence, but it seems to me that WordFence, no matter if real-time display activity is turned on or off, will nevertheless store all hits in the database — which actually makes some sort of sense, since it’s supposed to be processed for statistics at some point (or sent to WordFence’s central computers to investigate for new kinds of attacks). It seems logical that this information has to be stored somewhere and not simply discarded!
However, storing it on the database is a big no-no! The goal of any WordPress admin (well, any CMS admin, to be honest) is to have next to zero database accesses on any website, and let everything be statically served to clients, all from the disk (or, better, from memory). WordPress with nginx as the server can even sidestep PHP in several occasions, depending on how it is configured. That’s how you can achieve huge performances — only when the site really changes (i.e. when someone adds/updates an article or page) will there be a real need for the database to be accessed, and a new static page can be generated that way.
WordFence, somehow, subverts this concept, by ‘forcing’ all accesses to go through it. Note that this is just my assumption; the code is complex enough for me to be sure about what I’m saying! I can just tell that it appears to work that way.
Now, I understand that there is a dilemma here. On one hand, we all want to minimise database accesses, especially writes — these should be reduced to ‘next to zero’ (the only reason for not being zero is when a new article/page is posted/updated). On the other hand, we need WordFence to check via its firewall if all accesses are genuine, and somehow log them for processing them further at some point, elaborating statistics, or even sending them to a central storage where potential attacks can be identified and quickly stopped. This means that this information must be stored somewhere.
Again, not being familiar with the code, I have no idea if all the above is really true or not — just because it seems to be true (and it’s even logical that it works somehow in that fashion), it doesn’t mean that WordFence really works like that. But if it does, I would really wish for the ability to shut down all database writes — losing some statistics and such, but greatly improving overall performance, especially at the database level!
An alternative, of course, is writing the logs not to the database, but to an external file, which is kept open for this purpose. Because the writing can be buffered (even at the OS level), it might not be so tough in terms of performance. Of course, it means extra work when actually producing statistics, but the trade-off would be fine: statistics are not generated every fraction of a second (but perhaps just once per day… or per hour), while database writes from incoming site visitors can definitely pop up several times per second.
Another alternative would be to get access to the server logs. This, naturally enough, is only available to those WP admins who have total control over their hosting setup; the logs would have to be written on a directory that WordFence could ‘see’. In many cases, however, this is rather the norm than the exception (again, I’m talking only about personal experience; I have worked with just a handful of hosting providers, and they might all have been exceptional in giving public access to the server’s logs for our websites). The WordFence programmers would only need to adapt one of the many PHP libraries that extract information from an Apache/nginx access log, and produce all statistics from there instead. Note that it’s unlikely that a sysadmin will stop the access logs for their web server; so it means this kind of work would be done by the CPUs anyway, meaning that it would be pointless to duplicate the effort by writing one’s own logs. In some cases, however, the hosting provider will never give access to those logs, and that would mean that WordFence would have no option but to write on a disk file or add rows to the database.
Finally, if there are no other options, would it make sense to use the ARCHIVE engine for the table of hits? It is supposed to have much better performance for pure logging purposes. It would still require replication with lots of write operations, though…
Thank you for any input on this!
- The topic ‘WordFence creates a lot of database writes?’ is closed to new replies.