Version 7.1 of the free Go Live Update URLs plugin is now available and ready for general use. This release introduces an entirely new serialized data handler that improves both performance and security.
It is rare for us to write a release blog post for a basic plugin update, but this one is incredibly powerful and deserves to be announced.
Table Of Contents
New Serialized Data Handler
While we hadn’t seen any user issues with the previous structure, much of it was designed over 10 years ago. We were also alerted to an extremely hard-to-exploit security vulnerability inherent in PHP’s native unserialization process.
It was time to take a hard look to see if any modern PHP or WordPress enhancements could improve how we process data. Because modern PHP offers specialized ways to solve these problems, we decided to build our own custom serialized data handler to replace the native PHP version.
Not only were we able to maintain our ability to update deeply nested data better than any other plugin on the market, but we’ve improved the URL updating process across the board:
- 16× Faster Updates: Serialized data updates are significantly faster, with the biggest gains seen on large database rows.
- Lower Memory Usage: Peak memory usage is 3–5× lower on large serialized rows.
- Security Hardening: The plugin no longer runs database information through PHP’s
unserialize()function. Instead, it edits the stored text directly, meaning objects are never actively created during an update. - More Comprehensive: Rows that the old version silently skipped are now safely updated.
Improved Reliability
By taking full control over the unserialization process, we improved the reliability of data updates in several ways:
- Rows containing classes from deactivated or deleted plugins are now updated instead of skipped.
- Unchanged data stays byte-for-byte identical, preserving odd whitespace and exact formatting.
- URLs inside values containing NUL bytes are now updated correctly.
- Numbers are only changed when the whole value matches, and they maintain their exact type (e.g., an integer stays an integer).
- If a row cannot be read safely, it is skipped and logged once, ensuring data is never corrupted. Skipping one column no longer blocks updates to the row’s other columns.
- Extremely deeply nested data (up to 4,096 levels) is now fully supported.
Improved Performance
All WordPress sites store serialized data in their database. Updating that data is now significantly faster and consumes less memory, meaning every site will see a performance boost during updates. Sites with heavy serialized data—such as those built with modern page builders—will notice substantial improvements.
Why it’s faster:
- The plugin now reads serialized data as text in a single pass, rather than rebuilding every value in memory and writing it back out.
- Strings that do not contain the old URL are instantly skipped.
- Unchanged sections of data are copied as-is rather than being rebuilt from scratch.
- URL variants (like encoded, JSON-escaped, or over-escaped URLs) are calculated once per run instead of once per individual value.
Time improvements (relative to version 7.0.8)
| Data shape | PHP 8.5 | PHP 7.4 |
|---|---|---|
| Elementor template library (597 KB), one URL | 13.4× | 13.4× |
| Elementor template library, URLs in most strings | 6.2× | 6.5× |
| Deep page-builder object (13 levels) | 2.7× | 2.8× |
| Deep page-builder object, URLs in most strings | 1.7× | 1.8× |
| 20,000-key options array (750 KB) | 16.4× | 18.1× |
| 20,000-key options array, URLs in most strings | 6.0× | 6.3× |
2,000 typical wp_options/wp_postmeta rows | 10.5× | 9.7× |
| 2,000 typical rows, URLs in most strings | 6.9× | 7.6× |
Concrete timings on PHP 8.5:
- Elementor library: 89.5 ms → 6.7 ms
- 20,000-key options array: 215.9 ms → 13.2 ms (237.6 ms → 13.1 ms on PHP 7.4)
- 2,000 typical rows: 694.5 ms → 66.4 ms
Memory reductions:
- Elementor template peak memory dropped from 2.7 MB to 0.6 MB.
- Large options arrays dropped from 5.7 MB to 1.2 MB.
Developer Notes
- Introduced a new
Serialized_Parserclass and a newSerialized::reset_updater_urls()method. Serialized::replace_tree()andSkip_Rows::log_error()are deprecated and will be removed in version 8.0.- Table queries now use
%iidentifier placeholders for improved query stability. - The PHPStan baseline shrank by 66 lines.
Miscellaneous
- Tested to WordPress core version 7.1.1
- Required PRO version 7.1.4+