<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>museum-digital:blog - IIIF</title>
    <subtitle>A blog on museum-digital and the broader digitization of museum work.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://blog.museum-digital.org/tags/iiif/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://blog.museum-digital.org"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-01-12T00:00:00+00:00</updated>
    <id>https://blog.museum-digital.org/tags/iiif/atom.xml</id>
    <entry xml:lang="en">
        <title>State of Development, December 2025</title>
        <published>2026-01-12T00:00:00+00:00</published>
        <updated>2026-01-12T00:00:00+00:00</updated>


        
        <author>
          <name>Joshua Ramon Enslin</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://blog.museum-digital.org/2026/01/12/state-of-development-december-2025/"/>
        <id>https://blog.museum-digital.org/2026/01/12/state-of-development-december-2025/</id>
        
        <content type="html" xml:base="https://blog.museum-digital.org/2026/01/12/state-of-development-december-2025/">&lt;p&gt;December 2025 was an interesting month for museum-digital. An update to the PHP version used as well as a flood of requests by what is most likely AI scrapers forced us to make changes for improved stability, reducing and reformulating features rather than adding new ones and working on matters of systems administration over purely matters of code quite often. Add to that the long-promised update of the terms of use for German museums to more structured and lawyer-approved ones, and you get yet more small changes that do not directly concern the work of museums with museum-digital but rather improve the necessary context.&lt;/p&gt;
&lt;h2 id=&quot;musdb&quot;&gt;musdb&lt;/h2&gt;
&lt;h3 id=&quot;object-overview&quot;&gt;Object overview&lt;/h3&gt;
&lt;p&gt;In the default tile view of the object overview page, hovering over an object image thus far revealed the object’s name. As object names are often too long to display fully and inventory numbers are the primary means of identifying an object in most museums, this preview text has now been extended to include the inventory numer.&lt;/p&gt;
&lt;figure class=&quot;wp-block-image size-large&quot;&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.museum-digital.org/2026/01/12/state-of-development-december-2025/./20260112_musdb-object-list-1024x570.webp&quot; alt=&quot;Screenshot in the object overview.&quot; /&gt;&lt;figcaption class=&quot;wp-element-caption&quot;&gt;Hovering over an object image in the tile view now also displays the inventory number.&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h3 id=&quot;user-management&quot;&gt;User management&lt;/h3&gt;
&lt;h4 id=&quot;new-options-for-managing-user-accounts-disabling-accounts-setting-account-expiry-dates&quot;&gt;New Options for Managing User Accounts: Disabling Accounts &amp;amp; Setting Account Expiry Dates&lt;/h4&gt;
&lt;p&gt;Two new options on user editing pages allow disabling logins on an account and setting an expiry date for the account. Both can be useful for administration: If a new worker joins the museum for a project with a clear-cut limitation on funding and time, one can now set the account expiry at the beginning of the project to the end of it. The accounts will then automatically be deleted when the project ends. Similarly, colleagues that leave service temporarily but for a prolonged time (e.g. for a sabbatical) and will not need to use their accounts for that time can have their accounts disabled.&lt;/p&gt;
&lt;figure class=&quot;wp-block-image size-large&quot;&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.museum-digital.org/2026/01/12/state-of-development-december-2025/./20260112_musdb-user-options-1024x398.webp&quot; alt=&quot;Screenshot of the user editing page in musdb.&quot; /&gt;&lt;figcaption class=&quot;wp-element-caption&quot;&gt;Two new options allow disabling user accounts and setting expiry dates for user accounts.&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h4 id=&quot;list-of-terms-of-use&quot;&gt;List of Terms of Use&lt;/h4&gt;
&lt;p&gt;A new tab on a user’s (own) account settings page provides the option to list all usage agreements / terms of use a user has agreed to in the context of their use of museum-digital / musdb and when they agreed to them.&lt;/p&gt;
&lt;figure class=&quot;wp-block-image size-large&quot;&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.museum-digital.org/2026/01/12/state-of-development-december-2025/./20260112_musdb-user-agreement-list-1024x576.webp&quot; alt=&quot;Screenshot of the user editing page.&quot; /&gt;&lt;figcaption class=&quot;wp-element-caption&quot;&gt;A new tab on the user page lists all user agreements for musdb that the user has agreed to and when they did so.&lt;/p&gt;
&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h3 id=&quot;imports&quot;&gt;Imports&lt;/h3&gt;
&lt;h4 id=&quot;limiting-report-mail-size&quot;&gt;Limiting Report Mail Size&lt;/h4&gt;
&lt;p&gt;When a user runs imports themselves using the &lt;a rel=&quot;external&quot; href=&quot;https://de.handbook.museum-digital.info/import/importe-selbst-durchfuehren.html&quot;&gt;WebDAV upload&lt;/a&gt;, the end of the import process - no matter if it is successful or fails - is marked by the sending of a report via mail. This report usually contains a list of noteworthy operations that happened during the import, e.g. which objects of which inventory number were imported to which object in musdb, identified by its ID. As imports grow, this list of operation grows. To not encounter issues sending the report, it is henceforth limited to a maximum of 2 MB or 10000 lines.&lt;/p&gt;
&lt;h4 id=&quot;dry-run-mode&quot;&gt;Dry-run Mode&lt;/h4&gt;
&lt;p&gt;Sometimes it is useful to try running an import to see if it will actually work but not actually process any data. This option has been available in the importer command line interface for a while, among others powering &lt;a rel=&quot;external&quot; href=&quot;https://quality.museum-digital.org/&quot;&gt;museum-digital:qa&lt;/a&gt;. It is now available in the import configuration for self-run imports as well using the setting &lt;code&gt;dry-run&lt;/code&gt;. Enabling the setting accordingly stops the importer from actually writing the data into the database and changes the behavior if values that need to be mapped to values in controlled lists at museum-digital are encountered. Usually an import stops the moment such data is to be imported and not yet mapped. During a dry run, the error is collected and the import proceeds. All unmapped entries are listed together at the end of the import, allowing for a simpler mapping (possibly aided by &lt;a rel=&quot;external&quot; href=&quot;https://concordance.museum-digital.org/&quot;&gt;concordance.museum-digital.org&lt;/a&gt;).&lt;/p&gt;
&lt;h3 id=&quot;dashboard&quot;&gt;Dashboard&lt;/h3&gt;
&lt;p&gt;The first page of the dashboard, which for almost all users also means the start page of musdb right after the login process, was significantly reworked during the last month. The almost entirely unused notetaking features and discourse integration were removed in favor of a feed of recent blog posts. See also the section &lt;a href=&quot;https://blog.museum-digital.org/2025/12/29/trimming/&quot;&gt;“Communications”&lt;/a&gt; in the respective blog post.&lt;/p&gt;
&lt;figure class=&quot;wp-block-image size-large&quot;&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.museum-digital.org/2026/01/12/state-of-development-december-2025/./20251229_screenshot-musdb-1024x576.webp&quot; alt=&quot;Screenshot of the dashboard in musdb, as of 2025-12-29.&quot; /&gt;&lt;figcaption class=&quot;wp-element-caption&quot;&gt;The dashboard in musdb now features a feed of recent news relevant to the development of museum-digital and whatever is going on regionally. The posts are sorted chronologically.&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h3 id=&quot;annotations-for-the-vocabulary-editing-team&quot;&gt;Annotations for the Vocabulary Editing Team&lt;/h3&gt;
&lt;p&gt;Each event, displayed as a tile on object editing pages, featured speech bubble icons behind each time / actor / place to provide additional comments and hints for the central vocabulary editing team. This positioning of the annotation feature led to confusion over the years, with some users using the feature to comment on the relationship between the entity and the object (for which the event notes should be used). We hence repositioned the links and moved them to the respective entity’s page (e.g. a place page for giving hints and comments on a place entry). The hinting / commenting feature for times has been altogether removed, as providing comments to clarify the meaning of e.g. a year never made much sense.&lt;/p&gt;
&lt;h3 id=&quot;smaller-updates-and-bugfixes&quot;&gt;Smaller Updates and Bugfixes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Fixed a bug in the HTML generated for listing other objects linked to an object. Links to the other object were broken and are not anymore.&lt;/li&gt;
&lt;li&gt;Image editing pages now embed the image directly instead of using the IIIF API. This reduces resource usage and increases stability at no cost.&lt;/li&gt;
&lt;li&gt;Removed option to manually trigger the rewriting of EXIF and IPTC metadata of object images. Rewriting takes place in the background whenever an image or a linked object is updated, making user-triggered updates obsolete.&lt;/li&gt;
&lt;li&gt;Re-introduce option to repeat linking to the last used linked object&lt;/li&gt;
&lt;li&gt;Updated &lt;a rel=&quot;external&quot; href=&quot;https://swagger.io/&quot;&gt;Swagger UI&lt;/a&gt; to version 5.30.3&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;frontend&quot;&gt;Frontend&lt;/h2&gt;
&lt;p&gt;As stated above and lengthily described in the previous blog posts (&lt;a href=&quot;https://blog.museum-digital.org/2025/12/09/updates-ai-scrapers-and-resilience/&quot;&gt;here&lt;/a&gt;, &lt;a href=&quot;https://blog.museum-digital.org/2025/12/22/cleaning-out-our-closet/&quot;&gt;here&lt;/a&gt;, and &lt;a href=&quot;https://blog.museum-digital.org/2025/12/29/trimming/&quot;&gt;here&lt;/a&gt;) we struggled with stability over the last month. This means that most changes in the frontend are aimed at improving stability.&lt;/p&gt;
&lt;h3 id=&quot;reworked-default-image-page&quot;&gt;Reworked Default Image Page&lt;/h3&gt;
&lt;p&gt;Thoroughly described in &lt;a href=&quot;https://blog.museum-digital.org/2025/12/09/updates-ai-scrapers-and-resilience/&quot;&gt;Updates, AI scrapers, and Resilience&lt;/a&gt;, we replaced the default view for single object image pages. While the default view was previously built around the IIIF viewer Mirador, the new default view uses OpenLayers and the unmediated image file for capabilities such as zooming. The new view also brings with it some new features, such as an option to reference specific sections of an image.&lt;/p&gt;
&lt;figure class=&quot;wp-block-image size-large&quot;&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.museum-digital.org/2026/01/12/state-of-development-december-2025/./20260112_frontend-image-page-1024x672.webp&quot; alt=&quot;&quot; /&gt;&lt;figcaption class=&quot;wp-element-caption&quot;&gt;The reworked default image page.&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h3 id=&quot;serving-resource-intensive-pages-functionalities-only-when-resources-are-available&quot;&gt;Serving Resource-Intensive Pages / Functionalities Only When Resources Are Available&lt;/h3&gt;
&lt;p&gt;PDF generation, the IIIF Image API, and the suggestions for alternative search queries on failed search pages are now limited to reduce their impact on the overall system stability. This follows two strategies:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Suggestions on failed search pages and PDF generation will only appear if the overall load on the system is low. The threshold for when or when they are not provided is influenced by the user’s browser language: If a user uses a browser set to the primary language of a given instance of museum-digital (e.g. German in Hesse, Hungarian in Budapest), the threshold is much higher, meaning users will be able to access the pages at a medium server load. In the case of PDFs, high server load will forward users to the print dialogue for object pages instead of receiving a PDF generated on the server side.&lt;/li&gt;
&lt;li&gt;PDF generation and the IIIF Image API are served with a different PHP configuration and set of processes than the rest of the frontend. This configuration significantly reduces available resources for these two functionalities.&lt;/li&gt;
&lt;li&gt;The option to generate PDFs featuring all images of an object with between 10 and 40 images has been entirely removed. Given its constraints, the feature was hard to explain and rarely accessible anyway. The primary “users” were noticeably AI scrapers.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;image-search&quot;&gt;Image Search&lt;/h3&gt;
&lt;p&gt;The image search feature was refactored and reduced to further separate it from the primary object search. The number of available search options has been reduced to be more easily explainable and reduce possibilities for very resource-intensive queries.&lt;/p&gt;
&lt;figure class=&quot;wp-block-image size-large&quot;&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.museum-digital.org/2026/01/12/state-of-development-december-2025/./20260112_frontend-image-search-1024x602.webp&quot; alt=&quot;&quot; /&gt;&lt;figcaption class=&quot;wp-element-caption&quot;&gt;The reworked image search settings overlay.&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h3 id=&quot;batch-export-of-object-metadata-oai&quot;&gt;Batch Export of Object Metadata / OAI&lt;/h3&gt;
&lt;p&gt;Updated the LIDO API to almost entirely match the LIDO as generated during exports from musdb&lt;/p&gt;
&lt;h3 id=&quot;smaller-updates-and-bugfixes-1&quot;&gt;Smaller Updates and Bugfixes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Improved performance of object search by tags and places by filtering searched entities to those who are actually linked in the given instance of museum-digital.&lt;/li&gt;
&lt;li&gt;Object groups with only one object are henceforth not displayed and linked on object pages anymore&lt;/li&gt;
&lt;li&gt;Fixed link in footer: Clicking on “museum-digital” should lead to the home / start page of the given instance of musdb.&lt;/li&gt;
&lt;li&gt;Updated &lt;a rel=&quot;external&quot; href=&quot;https://swagger.io/&quot;&gt;Swagger UI&lt;/a&gt; to version 5.30.3&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;nodac&quot;&gt;nodac&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;User-provided comments / hints have been removed for times (see above)&lt;/li&gt;
&lt;li&gt;Tooltips for linked objects now display which institution an object belongs to
&lt;ul&gt;
&lt;li&gt;This is particularly important for vocabulary editors who do not have access to the museums’ data. This way they get a limited preview with the required information for unpublished objects despite their otherwise lacking permissions.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div
  class=&quot;my-4 flex flex-col rounded-lg bg-(--admonition-bg)&quot;
  style=&quot;--admonition-bg: var(--admonition-info);&quot;
&gt;
  &lt;div class=&quot;flex items-center rounded-t-lg bg-(--admonition-bg) p-1&quot;&gt;
    &lt;div
      class=&quot;mx-2 h-4 w-4 text-[0px] [background:var(--url)_center_center_no-repeat] dark:invert&quot;
      style=&quot;--url: url(icons/info.svg);&quot;
    &gt;
      info
    &lt;/div&gt;
    &lt;span&gt;&lt;strong&gt;AI Use&lt;/strong&gt;&lt;/span&gt;
  &lt;/div&gt;
  &lt;div class=&quot;pl-4&quot;&gt;&lt;p&gt;&lt;em&gt;(Post image generated using AI)&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div
  class=&quot;my-4 flex flex-col rounded-lg bg-(--admonition-bg)&quot;
  style=&quot;--admonition-bg: var(--admonition-info);&quot;
&gt;
  &lt;div class=&quot;flex items-center rounded-t-lg bg-(--admonition-bg) p-1&quot;&gt;
    &lt;div
      class=&quot;mx-2 h-4 w-4 text-[0px] [background:var(--url)_center_center_no-repeat] dark:invert&quot;
      style=&quot;--url: url(icons/info.svg);&quot;
    &gt;
      info
    &lt;/div&gt;
    &lt;span&gt;&lt;strong&gt;License&lt;/strong&gt;&lt;/span&gt;
  &lt;/div&gt;
  &lt;div class=&quot;pl-4&quot;&gt;&lt;p&gt;This content is licensed under a &lt;a rel=&quot;external&quot; href=&quot;https://creativecommons.org/licenses/by/4.0/&quot;&gt;Creative Commons Attribution 4.0 International license&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</content>

        
        
        <post-thumbnail><url>https://blog.museum-digital.org/2026/01/12/state-of-development-december-2025/20260112_News-Img-1.webp</url></post-thumbnail>
        
        
    </entry>
    <entry xml:lang="en">
        <title>Updates, AI scrapers, and Resilience</title>
        <published>2025-12-09T00:00:00+00:00</published>
        <updated>2025-12-09T00:00:00+00:00</updated>


        
        <author>
          <name>Joshua Ramon Enslin</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://blog.museum-digital.org/2025/12/09/updates-ai-scrapers-and-resilience/"/>
        <id>https://blog.museum-digital.org/2025/12/09/updates-ai-scrapers-and-resilience/</id>
        
        <summary type="html">Between Thursday last week (November 27th) and yesterday (December 6th), museum-digital has seen its most instable week in about four years. Now that the dust has settled a bit, there&#39;s finally some time to discuss what happened and how we managed to tackle the multiple issues leading to the (very noticeable) instability.</summary>
        
        <content type="html" xml:base="https://blog.museum-digital.org/2025/12/09/updates-ai-scrapers-and-resilience/">&lt;p&gt;Between Thursday last week (November 27th) and yesterday (December 6th), museum-digital has seen its most unstable week in about four years. Now that the dust has settled a bit, there’s finally some time to discuss what happened and how we managed to tackle the multiple issues leading to the (very noticeable) instability.&lt;/p&gt;
&lt;h2 id=&quot;background&quot;&gt;Background&lt;/h2&gt;
&lt;h3 id=&quot;scrapers&quot;&gt;Scrapers&lt;/h3&gt;
&lt;p&gt;There were (or are) two factors simultaneously pushing our servers to their limits and requiring changes. On the one hand, scraping of museum-digital has gotten even more aggressive. Where we usually has something around 10-30 requests per second across all of museum-digital a year ago, we had around 300 two weeks ago. Right now it’s often between 500 and 700. This number excludes any access to static files.&lt;/p&gt;
&lt;p&gt;As I’ve written elsewhere, the scrapers are mostly noticable by coming from IP ranges in Asia or (to a lesser extent) the US. On the other hand, the IPs change constantly and user-agents etc. resemble regular users. Likely they simply use an actual chrome browser for scraping. Which is to say, attempting to block them is futile. Worse yet, attempts to block scrapers would likely also impact some real users.&lt;/p&gt;
&lt;p&gt;Fortunately museum-digital is run on dedicates servers paid by time rather than by compute. The onslaught of scrapers thus has no financial impact on us. But the scrapers still use resources, and as they try to scrape as many different pages as possible, it is much harder to optimize for them than it is to optimize for actual human users (see this article on a similar issue at &lt;a rel=&quot;external&quot; href=&quot;https://arstechnica.com/information-technology/2025/04/ai-bots-strain-wikimedia-as-bandwidth-surges-50/&quot;&gt;Wikimedia&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Either way, AI scrapers can result in improvements. Viewed positively, they essentially act as a free stress test on a service and enforce efficiency in all aspects. If most pages are optimized for performance already, scrapers will find the unoptimized ones and bring down a service by overusing those. Which is to say, they help to identify yet unoptimized scripts/pages/classes and enforce that necessary changes are made. At museum-digital, there are three main weak spots that are hard to optimize: timelines, image manipulation (including the IIIF API), and PDF generation.&lt;/p&gt;
&lt;h3 id=&quot;php&quot;&gt;PHP&lt;/h3&gt;
&lt;p&gt;On November 20th PHP 8.5 was released. Thus far, museum-digital had been running on PHP 8.3 for web hosting and PHP 8.4 on the command line. When we attempted to update to 8.4 last year, the server fell over. This was mainly caused by the IIIF API (and thus, image manipulation via &lt;a rel=&quot;external&quot; href=&quot;https://www.libvips.org/&quot;&gt;libvips&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Dependencies at museum-digital are (like pretty much universal with PHP) handled using the package manager &lt;code&gt;composer&lt;/code&gt;. Setting up a new instance of museum-digital, composer (managed on version 8.4) required PHP 8.4 or later to run - the new instance was thus unable, being stuck on version 8.3 for hosting.&lt;/p&gt;
&lt;p&gt;That leaves two options: Either to set up composer using PHP 8.3 again, or to simply update everything to the current version. While PHP 8.3 will be &lt;a rel=&quot;external&quot; href=&quot;https://www.php.net/supported-versions.php&quot;&gt;supported until 2027&lt;/a&gt;, it is generally advisable to update when possible. So updating it was.&lt;/p&gt;
&lt;p&gt;Importantly, PHP at museum-digital is run via &lt;a rel=&quot;external&quot; href=&quot;https://www.php.net/manual/de/install.fpm.php&quot;&gt;PHP-FPM&lt;/a&gt;. Before the update, we had one socket running per subdomain. This means, that if a PHP process serving the frontend stopped working for any reason, users in musdb were impacted as well.&lt;/p&gt;
&lt;h2 id=&quot;upgrading-php-to-version-8-5&quot;&gt;Upgrading PHP to version 8.5&lt;/h2&gt;
&lt;p&gt;Once we upgraded the PHP version to 8.5 on Thursday, the same problems we faced with PHP 8.4 appeared again. The server would run rather smoothly for some hours, then more and more PHP processes would die and PHP-FPM would fall over for a given subdomain, and users would get a 504 gateway timeout error. Again, the IIIF API and image manipulation were the main causes of PHP-FPM getting stuck. Of course, the number of AI scrappers continuing to use the site did not help.&lt;/p&gt;
&lt;h3 id=&quot;php-fpm-settings&quot;&gt;PHP-FPM settings&lt;/h3&gt;
&lt;p&gt;A natural first point to consider was the configuration of PHP-FPM. PHP-FPM knows three basic modes for running an application:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ondemand&lt;/code&gt; You define a maximum number of processes the application may use. When a new request is made, idle processes get used. If there is no idle process, PHP-FPM starts a new one. After a specified number of requests or a given number of seconds, an old process is closed. This is primarily aimed at being able to scale way down - if there is no requests, there will be no processes (which is to say, less resources used). On the other hand, starting new processes takes time.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;static&lt;/code&gt; You define a number of processes that should always be running for the application. This means that there should always be processes already started and ready for usage, but it also means that those processes take up resources even when they are little used. Which is to say, this is useful if one has a high and constant stream of users.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dynamic&lt;/code&gt; You define a maximum number of processes, as well as how many processes should be always running for immediate use, and a (minimum and maximum) number of spare processes to keep running. PHP-FPM then manages if more processes should be started or if one of the already running ones shall be used. This, in theory, is useful if one wants to reliably and quickly serve users, expects some use all the time, but wants the server to dynamically scale up and down as needed.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With museum-digital spread out over around 80 subdomains, we had thus far used the &lt;code&gt;ondemand&lt;/code&gt; mode for most subdomains. Only the largest and most used instances / subdomains of museum-digital were run using &lt;code&gt;dynamic&lt;/code&gt; mode. With the update to PHP 8.4 and then 8.5, the behavior of the &lt;code&gt;ondemand&lt;/code&gt; mode seems to have changed. If one process dies, the whole subdomain goes seems to go down with it (I have not found a documentation on this, but it’s evident from the last two weeks).&lt;/p&gt;
&lt;p&gt;We hence moved critical subdomains impacted by the errors (which is to say, any “regular” instance of museum-digital) to dynamic mode. As dynamic mode enforces stricter limits on how many processes can be run respective to the available hardware (which is to say, dynamic mode requires a better-written configuration), this also meant that we needed to adjust the specified numbers of processes per subdomain according to their use.&lt;/p&gt;
&lt;p&gt;To actually grasp &lt;em&gt;real&lt;/em&gt; use of a subdomain including bots, we turned to the logs we keep for about a week (and then rotate out). In server logs, usually one line corresponds to a single request. With a small script, we loop all the different subdomains and check how many requests were made. To be really sure that only requests to relevant PHP scripts are processed, we filter them by the presence of the substring “php” before counting. The result for today between 1 a.m. and 4 p.m. looks as follows:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#000000, #E6EDF3); background-color: light-dark(#FFFFFF, #0D1117);&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| Requests count in instance                         |      Total |      musdb |        PDF | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| -----                                              |      ----- |      ----- |      ----- | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| agrargeschichte.museum-digital.de                  |     341508 |       1245 |        719 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| bawue.museum-digital.de                            |     454228 |      12559 |       6819 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| bayern.museum-digital.de                           |     176291 |          0 |        158 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| berlin.museum-digital.de                           |     223280 |      14917 |       6814 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| brandenburg.museum-digital.de                      |      63286 |       6927 |       3873 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| bremen.museum-digital.de                           |     221208 |          0 |       2026 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| bund.museum-digital.de                             |        261 |        167 |          5 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| collectors.museum-digital.de                       |     108398 |        449 |        648 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| hamburg.museum-digital.de                          |      35489 |          0 |         11 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| hessen.museum-digital.de                           |      50932 |       7962 |       2486 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| meckpomm.museum-digital.de                         |      94177 |         11 |        139 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| nds.museum-digital.de                              |     137703 |       4105 |       4134 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| owl.museum-digital.de                              |     427667 |       1258 |       2412 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| rheinland.museum-digital.de                        |      64838 |       1753 |       1276 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| rlp.museum-digital.de                              |     207944 |       7405 |       7532 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| sachsen.museum-digital.de                          |     120931 |      16117 |       6034 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| saarland.museum-digital.de                         |        210 |          0 |          1 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| smb.museum-digital.de                              |     228542 |          0 |      11517 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| sh.museum-digital.de                               |      21098 |          0 |         48 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| st.museum-digital.de                               |     317913 |       6243 |       6217 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| thue.museum-digital.de                             |     117893 |          0 |        495 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| westfalen.museum-digital.de                        |     101584 |       2033 |       3310 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| br.museum-digital.org                              |      43413 |          0 |         16 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| jateng.id.museum-digital.org                       |        211 |          0 |          0 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| jatim.id.museum-digital.org                        |      23410 |          0 |        159 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| lazio.it.museum-digital.org                        |        295 |          0 |          0 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| ma.pl.museum-digital.org                           |        385 |          0 |          0 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| noe.at.museum-digital.org                          |     906386 |          0 |        369 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| tirol.at.museum-digital.org                        |        537 |          0 |          7 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| vbg.at.museum-digital.org                          |         96 |          0 |          0 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| wien.at.museum-digital.org                         |     472305 |        586 |       3243 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| ulster.ie.museum-digital.org                       |      28869 |          0 |          2 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| connacht.ie.museum-digital.org                     |        392 |          0 |          0 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| va.srb.museum-digital.org                          |       5599 |          0 |         22 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| ko.rou.museum-digital.org                          |       9036 |        635 |        567 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| mm.rou.museum-digital.org                          |        235 |          0 |          0 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| ca.usa.museum-digital.org                          |       3946 |          0 |          0 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| ma.usa.museum-digital.org                          |        357 |          0 |          0 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| ny.usa.museum-digital.org                          |      19576 |          0 |        294 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| syddanmark.dk.museum-digital.org                   |        675 |          0 |          9 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| de.pt.museum-digital.org                           |       1241 |          0 |         29 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| zh.ch.museum-digital.org                           |     233280 |        512 |        650 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| ba.hu.museum-digital.org                           |      99927 |       1901 |         72 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| be.hu.museum-digital.org                           |     100830 |        244 |       3005 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| bk.hu.museum-digital.org                           |     489446 |         55 |       3985 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| bu.hu.museum-digital.org                           |     213616 |       6206 |       5753 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| bz.hu.museum-digital.org                           |     598550 |        680 |       1788 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| cs.hu.museum-digital.org                           |      88585 |          0 |       1054 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| fe.hu.museum-digital.org                           |     199812 |          7 |        215 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| gs.hu.museum-digital.org                           |     216680 |       4215 |        912 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| hb.hu.museum-digital.org                           |      61250 |          0 |         65 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| he.hu.museum-digital.org                           |      26312 |          7 |         26 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| jn.hu.museum-digital.org                           |      11970 |          0 |        131 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| ke.hu.museum-digital.org                           |     370219 |       2959 |       1680 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| no.hu.museum-digital.org                           |     119487 |          0 |       1545 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| pe.hu.museum-digital.org                           |     603846 |       2957 |       1446 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| so.hu.museum-digital.org                           |     308116 |       6151 |       6698 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| sz.hu.museum-digital.org                           |        116 |          0 |          0 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| to.hu.museum-digital.org                           |      52406 |          0 |       1229 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| va.hu.museum-digital.org                           |     184231 |       2839 |       1666 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| ve.hu.museum-digital.org                           |    1015509 |       3672 |        296 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| za.hu.museum-digital.org                           |        199 |          0 |          6 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| ce.cz.museum-digital.org                           |          3 |          0 |          0 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| ccc.cz.museum-digital.org                          |         17 |          0 |          0 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| academia.hu.museum-digital.org                     |       9158 |          0 |         13 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| cherkasy.ua.museum-digital.org                     |      25567 |          0 |         26 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| chernihiv.ua.museum-digital.org                    |       3258 |         99 |        156 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| dnipro.ua.museum-digital.org                       |      26725 |          0 |        109 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| donetsk.ua.museum-digital.org                      |         17 |          0 |          0 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| ivfr.ua.museum-digital.org                         |        722 |          0 |          9 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| kharkiv.ua.museum-digital.org                      |      12932 |          0 |         39 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| kyiv.ua.museum-digital.org                         |     436482 |       5967 |       1351 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| kyivska.ua.museum-digital.org                      |       2159 |          0 |         79 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| lviv.ua.museum-digital.org                         |     163358 |        188 |        274 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| poltava.ua.museum-digital.org                      |       7657 |        284 |          3 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| odesa.ua.museum-digital.org                        |         93 |          0 |          1 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| rivne.ua.museum-digital.org                        |      59510 |         65 |        156 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| sumy.ua.museum-digital.org                         |      35890 |        303 |          3 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| ternopil.ua.museum-digital.org                     |     150700 |         37 |        184 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| zhytomyr.ua.museum-digital.org                     |          3 |          0 |          0 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| vinnytsia.ua.museum-digital.org                    |      14229 |          0 |          0 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| volyn.ua.museum-digital.org                        |      16705 |          0 |        485 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| zakarpattia.ua.museum-digital.org                  |       2865 |          0 |         30 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| zaporizhzhia.ua.museum-digital.org                 |      24348 |        338 |         56 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| scotland.museum-digital.org                        |          0 |          0 |          0 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| md.museum-digital.org                              |          0 |          0 |          0 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| demo.museum-digital.org                            |         12 |          2 |          0 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| goethehaus.museum-digital.de                       |     260072 |          0 |         85 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| lmw.museum-digital.de                              |     326724 |          0 |         65 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| gedenkstaetten.museum-digital.de                   |       3474 |          0 |          0 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| turcica.museum-digital.de                          |      75533 |          0 |          1 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| nat.museum-digital.de                              |    1238860 |          0 |       4657 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| at.museum-digital.org                              |     631578 |          0 |         89 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| cz.museum-digital.org                              |          2 |          0 |          0 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| dk.museum-digital.org                              |       5415 |          0 |          4 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| hu.museum-digital.org                              |     359619 |          0 |       2827 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| id.museum-digital.org                              |       8030 |          0 |          0 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| ie.museum-digital.org                              |       2073 |          0 |          0 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| it.museum-digital.org                              |         78 |          0 |          0 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| rou.museum-digital.org                             |       8277 |          0 |        466 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| pl.museum-digital.org                              |        142 |          0 |          0 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| pt.museum-digital.org                              |          0 |          0 |          0 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| srb.museum-digital.org                             |        565 |          0 |          0 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| ua.museum-digital.org                              |     232115 |          0 |        805 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| usa.museum-digital.org                             |       3752 |          0 |         34 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| ch.museum-digital.org                              |      53417 |          0 |          1 | &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| global.museum-digital.org                          |     727690 |          0 |       2199 |&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that the number of requests obviously is also impacted by bots changing attention - once a scraper is done with one subdomain, they turn to the next. The elevated number of requests in ve.hu.museum-digital.org is normal, but still starkly exaggerated when compared to other days. The Germany-wide instance is persistently the most frequented one, usually the global one is second at around 80% of requests.&lt;/p&gt;
&lt;p&gt;Now equipped with actual numbers, we could scale the PHP-FPM to a much more suitable configuration than before (we had thus far never bothered counting actual requests, instead relying on the number of objects).&lt;/p&gt;
&lt;p&gt;A second step in the PHP-FPM configuration was to reduce the impact the problems had. Previously there was one shared configuration and socket per subdomain. On the one hand, this meant that stuck processes in the frontend impacted users in musdb (and vice-versa). On the other hand, some constraints on resource usage cannot be set on a per-directory level but must be set per PHP-FPM socket / server (see the PHP documentation on &lt;a rel=&quot;external&quot; href=&quot;https://www.php.net/manual/en/configuration.file.per-user.php&quot;&gt;user.ini&lt;/a&gt; and the list of &lt;a rel=&quot;external&quot; href=&quot;https://www.php.net/manual/en/ini.list.php&quot;&gt;php.ini directives&lt;/a&gt;). As the frontend and musdb have different requirements (frontend: low maximum memory use, short timeouts, no file uploads, generally strict settings; musdb: long timeouts for uploads, generally more lenient), being able to configure them independent of each other is useful in general.&lt;/p&gt;
&lt;p&gt;We thus separated the configuration for the frontend, musdb, and PDF generation in the frontend; providing dedicated sockets for each. The frontend has a reduced &lt;a rel=&quot;external&quot; href=&quot;https://de.wikipedia.org/wiki/Nice_(Unix)&quot;&gt;priority&lt;/a&gt; on the system overall, strict constraints on how it may be used, etc. The settings are stricter than they were before. musdb has an elevated priority and more lenient settings (file uploads, longer timeouts), in fact more lenient than before. Finally, PDF generation is a special case as it offers no real benefit over the browser’s print tool (see MDN on &lt;a rel=&quot;external&quot; href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Media_queries/Printing&quot;&gt;print CSS&lt;/a&gt;), while being resource-intensive. As such, it has a far reduced priority and very strict settings.&lt;/p&gt;
&lt;p&gt;With the separated configuration and sockets, we can now better tailor the configuration to each application’s needs and have the added benefit of problems in one application not impacting the other.&lt;/p&gt;
&lt;h3 id=&quot;code&quot;&gt;Code&lt;/h3&gt;
&lt;p&gt;As we had already prepared the codebase for PHP 8.4 awaiting an eventual upgrade, the upgrade to PHP 8.5 only required minimal changes. Aside from the deprecation of the functions &lt;code&gt;finfo_close()&lt;/code&gt; and &lt;code&gt;curl_close()&lt;/code&gt;, references to which were accordingly removed from the code, the update necessitated no further work.&lt;/p&gt;
&lt;h2 id=&quot;scaling-in-software&quot;&gt;Scaling in Software&lt;/h2&gt;
&lt;p&gt;Improving the PHP configuration was not enough to fix the issues, especially with the now increased number of requests from bots. To get some breathing room, we adjusted the most resource-intensive pages.&lt;/p&gt;
&lt;h3 id=&quot;frontend&quot;&gt;Frontend&lt;/h3&gt;
&lt;p&gt;In the frontend these are, again, the IIIF API, PDF generation, and timelines. Finally, we made changes to the pages for failed searches to better handle high load situations.&lt;/p&gt;
&lt;h4 id=&quot;image-pages&quot;&gt;Image pages&lt;/h4&gt;
&lt;p&gt;The IIIF API was used for the main image pages in the frontend. We used (and use) &lt;a rel=&quot;external&quot; href=&quot;https://projectmirador.org/&quot;&gt;Mirador&lt;/a&gt; as a IIIF viewer. Simply opening an image page thus meant three requests to fetch different regions of an image. Zooming into the image triggered further requests to fetch the relevant parts of the image. Cropping the image to the requested region with IIIF happens on the server (which is no problem if there are few users, but is turning into a problem when you have hundreds of requests per second).&lt;/p&gt;
&lt;p&gt;We thus changed the default of image pages: The new default image page is the old, non-IIIF one. As features like zooming into images, that Mirador comes with, are popular and useful and the old image page did not support those, we worked to improve the page. To do so, we rely on &lt;a rel=&quot;external&quot; href=&quot;https://openlayers.org/&quot;&gt;OpenLayers&lt;/a&gt;, a library we already use for maps. Besides including maps from tile servers, OpenLayers also supports loading simple image files - which we do here. The image is hence loaded once in full size and zooming etc. happen entirely in the browser.&lt;/p&gt;
&lt;p&gt;Taking the opportunity, we improved the page overall. An often noticed problem of image pages thus far was, that users who opened image pages coming from external services (think Google Images) had problems identifying that the image was an object image and that there is further object data to be found on object pages. The updated image pages now come with a header stating reflecting the name of the image, the name of the object and the name of the institution. Note that many images do not feature a dedicated title, musdb uses the object name as a default image title in that case, which is why the object title will often appear twice in the header. Maybe this can be used as an encouragement for the colleagues working in musdb to more consistently set expressive image titles in the future.&lt;/p&gt;
&lt;p&gt;Also new is a mini map at the bottom left, displaying where in the wider context of the image one has currently zoomed in, as well as the ability to link exactly the region one has currently zoomed into. To enable the latter, the URL updates as one zooms or navigates around the image. Somebody else opening the same URL will then open exactly the same image region the linking person was viewing when copying the URL. Finally, we finally set specific &lt;a rel=&quot;external&quot; href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP&quot;&gt;Content Security Policies&lt;/a&gt; relevant to the currently opened media. If the displayed media entry is an internally stored image, no external images need to be allowed to load. If the displayed media entry is an audio file stored on archive.org, archive.org needs to be whitelisted as a source for audio files - but only archive.org and no other page. Previously, embedding images from anywhere on the net was allowed, increasing the potential damage a potential attacker may cause.&lt;/p&gt;
&lt;p&gt;Making the use of Mirador a secondary, non-default option reduced the need for server-side image manipulation and the corresponding resource use significantly. The IIIF remains largely unchanged, but its use must now be requested explicitly.&lt;/p&gt;
&lt;h4 id=&quot;pdf-generation&quot;&gt;PDF generation&lt;/h4&gt;
&lt;p&gt;As stated above, PDF generation brings little advantages to the browser’s print functionality in combination with object pages. On the contrary, the PDFs generated using the frontend’s templates feature less information. But they come with the file ending “.pdf” and seem to be extremely popular with bots. On the other hand, PDF generation means, among others, loading whatever images are to be embedded into the PDF and manipulating them fit into the PDF. The resulting files are significantly larger than the corresponding HTML files and thus also use more of the available bandwidth.&lt;/p&gt;
&lt;p&gt;The update to handle PDF generation respective to resource usage was already introduced in the last months: publicly linked PDFs are now only generated if overall load on the server is low, if a user has set their &lt;a rel=&quot;external&quot; href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Accept-Language&quot;&gt;browser language&lt;/a&gt; to any language different from a museum-digital instance’s default language. As most scrapers do not bother to change their browser language (which means they come with either none, English or Chinese), this means they will mostly be unable to trigger the generation of PDFs. They see an error page instead.&lt;/p&gt;
&lt;h4 id=&quot;failed-search-pages&quot;&gt;Failed Search Pages&lt;/h4&gt;
&lt;p&gt;If a user tries to execute a search query without any results, they will get suggestions for similar search terms - similar to how Google will ask one searching for “Berrlin”, if they meant “Berlin”. Trying to identify suitable suggestions obviously costs resources and whether the suggestions are actually what a user wanted is by nature hit or miss - it’s suggestions after all. In the case of scrapers, suggesting alternative search queries offers them a never-ending stream of possible search queries to run and keep scraping the subdomain with - to nobody’s benefit (not even the scrapers’, as they likely got the same content with other search queries already).&lt;/p&gt;
&lt;p&gt;We thus now use the same function used to identify whether PDFs should be generated for a user to check if search suggestions should be provided. It a user comes with a non-default browser language and resource use is high, no suggestions will be provided.&lt;/p&gt;
&lt;h4 id=&quot;timelines&quot;&gt;Timelines&lt;/h4&gt;
&lt;p&gt;Timeline pages as implemented in museum-digital’s frontend offer another source of endless links and search queries, as they link to further and further specifications of the time searched by. Again, an improvement already introduced months ago, was to better parse queries by time: If a user searches for objects that are linked to times “after 1920” and “after 1930”, the latter already includes the former. “After 1920 and after 1930” means exactly the same as “after 1930”. Which is one &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Join_(SQL)&quot;&gt;join&lt;/a&gt; instead of two - half the resource usage.&lt;/p&gt;
&lt;p&gt;A minor improvement we noticed on the side was impact of automatic redirects in the timelines. Say, a user searches objects by their link to a given tag and then generates a timeline for said objects. If all objects were created in the 20th century, the timeline will automatically redirect so as to “zoom” into a more appropriate time scale than from the big bang to now. Until the last weekend, script execution was not stopped when that redirect happened - which means that all database queries for time time from the big bang to now were still executed even though the user never got to see them. That is now fixed.&lt;/p&gt;
&lt;h2 id=&quot;the-anti-climactical-solution&quot;&gt;The Anti-Climactical Solution&lt;/h2&gt;
&lt;p&gt;All of those changes got the frontend more or less stable. Problems with uploading images remained however. Finally, the only thing that helped was uninstalling libvips (which we use for image manipulation) and reinstalling it. That seems to have fixed the issues.&lt;/p&gt;
&lt;p&gt;Especially as the number of requests from scrapers continues to increase, the current strategy outlined above seems to be fruitful. By reducing the use (and sometimes the availability altogether) of especially resource-intensive and - depending on the context - little useful functionalities, much stability and can be gained.&lt;/p&gt;
&lt;p&gt;The update seems to finally be largely completed (aside from maybe some further fine-tuning of the PHP-FPM configuration) and museum-digital is stable despite the bot problem, while we haven’t had to take more drastic or costly actions yet - such as blocking or adding additional servers.&lt;/p&gt;
&lt;div
  class=&quot;my-4 flex flex-col rounded-lg bg-(--admonition-bg)&quot;
  style=&quot;--admonition-bg: var(--admonition-info);&quot;
&gt;
  &lt;div class=&quot;flex items-center rounded-t-lg bg-(--admonition-bg) p-1&quot;&gt;
    &lt;div
      class=&quot;mx-2 h-4 w-4 text-[0px] [background:var(--url)_center_center_no-repeat] dark:invert&quot;
      style=&quot;--url: url(icons/info.svg);&quot;
    &gt;
      info
    &lt;/div&gt;
    &lt;span&gt;&lt;strong&gt;AI Use&lt;/strong&gt;&lt;/span&gt;
  &lt;/div&gt;
  &lt;div class=&quot;pl-4&quot;&gt;&lt;p&gt;&lt;em&gt;(Post image AI-generated using Z-Image)&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div
  class=&quot;my-4 flex flex-col rounded-lg bg-(--admonition-bg)&quot;
  style=&quot;--admonition-bg: var(--admonition-info);&quot;
&gt;
  &lt;div class=&quot;flex items-center rounded-t-lg bg-(--admonition-bg) p-1&quot;&gt;
    &lt;div
      class=&quot;mx-2 h-4 w-4 text-[0px] [background:var(--url)_center_center_no-repeat] dark:invert&quot;
      style=&quot;--url: url(icons/info.svg);&quot;
    &gt;
      info
    &lt;/div&gt;
    &lt;span&gt;&lt;strong&gt;License&lt;/strong&gt;&lt;/span&gt;
  &lt;/div&gt;
  &lt;div class=&quot;pl-4&quot;&gt;&lt;p&gt;This content is licensed under a &lt;a rel=&quot;external&quot; href=&quot;https://creativecommons.org/licenses/by/4.0/&quot;&gt;Creative Commons Attribution 4.0 International license&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</content>

        
        
        <post-thumbnail><url>https://blog.museum-digital.org/2025/12/09/updates-ai-scrapers-and-resilience/AI-gen-dove-and-robots-scaled.webp</url></post-thumbnail>
        
        
    </entry>
    <entry xml:lang="en">
        <title>IIIF and museum-digital</title>
        <published>2022-04-03T00:00:00+00:00</published>
        <updated>2022-04-03T00:00:00+00:00</updated>


        
        <author>
          <name>Joshua Ramon Enslin</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://blog.museum-digital.org/2022/04/03/iiif-and-museum-digital/"/>
        <id>https://blog.museum-digital.org/2022/04/03/iiif-and-museum-digital/</id>
        
        <content type="html" xml:base="https://blog.museum-digital.org/2022/04/03/iiif-and-museum-digital/">&lt;p&gt;Many have seen it and the feedback has been consistently positive thus far: For many objects, museum-digital can now offer a revamped image viewer with improved features, such as a much better zoom function. This is made possible by the image viewer Mirador and our IIIF API.&lt;/p&gt;
&lt;figure class=&quot;wp-block-image size-large is-resized&quot;&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.museum-digital.org/2022/04/03/iiif-and-museum-digital/./IIIF-Mirador-Collection-1024x576.jpg&quot; alt=&quot;&quot; /&gt;&lt;figcaption&gt;The collection of paintings of the Stiftung Preußische Schlösser und Gärten as a IIIF Collection in Mirador’s demo instance&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;The fact that museum-digital offers an IIIF API at all, and that a IIIF viewer ist now used at museum-digital, is noteworthy, but quick to report. Especially, since both IIIF and Mirador are very well-documented on their own websites (&lt;a rel=&quot;external&quot; href=&quot;https://iiif.io/&quot;&gt;IIIF&lt;/a&gt; und &lt;a rel=&quot;external&quot; href=&quot;https://projectmirador.org/&quot;&gt;Mirador&lt;/a&gt;r).&lt;/p&gt;
&lt;p&gt;But if one looks into it deeply, it becomes obvious, that the IIIF-based image view is not available for all objects.&lt;/p&gt;
&lt;h2 id=&quot;limitations-of-museum-digital-s-implementation-of-iiif&quot;&gt;Limitations of museum-digital’s implementation of IIIF&lt;/h2&gt;
&lt;p&gt;IIIF offers a standardized API format for retrieving image metadata through an appropriately formulated URL, but it also enables the retrieval of image files that are cropped or rotated accordingly on the server side. This server-side image editing is useful for making IIIF-based applications run on low-powered devices and it provides easily referencable URLs for specific sections of an image. But it also means, that all images made available through the IIIF API should be available on the server itself in a high resolution.&lt;/p&gt;
&lt;p&gt;At museum-digital, museums can upload their images - but since some museums have their own image servers, museums can also link images from external sources. In this latter case, museum-digital only stores previews up to a width of 500 pixels. These previews are however not usable for an adequate server-side image editing as required for implementing IIIF. Thus we offer IIIF manifests only for objects that exclusively have locally stored images.&lt;/p&gt;
&lt;p&gt;We currently also implement IIIF only in version 2.1, which does not yet support other media types such as PDFs, videos, audio files or 3D representations of objects. Hence, objects that have any linked representations of these types are also excluded from the IIIF API.&lt;/p&gt;
&lt;h2 id=&quot;iiif-collections&quot;&gt;IIIF Collections&lt;/h2&gt;
&lt;p&gt;One of the nicer features of IIIF are IIIF collections, with which many objects / manifests can be grouped into a collection. For implementing the minimal requirements for an IIIF API two years ago, we had thus far already set up the relevant files for IIIF collections - but we didn’t fill them with contents.&lt;/p&gt;
&lt;p&gt;Now, IIIF collections at museum-digital represent collections and object groups. The limitations described above persist however: IIIF collections at museum-digital only list objects with exclusively internally stored images.&lt;/p&gt;
&lt;p&gt;IIIF collections can be accessed - as always - by their respective URL. E.g.:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#000000, #E6EDF3); background-color: light-dark(#FFFFFF, #0D1117);&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;https://brandenburg.museum-digital.de/apis/iiif-presentation/collection/c217&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This URL represents the collections of paintings of the Stiftung Preußische Schlösser und Gärten. The noteworthy section is the last: c217. Since the IIIF collection API at museum-digital represents three different types of groupings at once - institutions, collections, and series / object groups - the first character of this URL section represents the respective type of grouping. The ID of the entry follows.&lt;/p&gt;
&lt;p&gt;An “i” in front of the ID thus represents institutions, an “s” represents series. One example of a IIIF collection for an object group may thus be:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#000000, #E6EDF3); background-color: light-dark(#FFFFFF, #0D1117);&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;https://hessen.museum-digital.de/apis/iiif-presentation/collection/s20&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div
  class=&quot;my-4 flex flex-col rounded-lg bg-(--admonition-bg)&quot;
  style=&quot;--admonition-bg: var(--admonition-info);&quot;
&gt;
  &lt;div class=&quot;flex items-center rounded-t-lg bg-(--admonition-bg) p-1&quot;&gt;
    &lt;div
      class=&quot;mx-2 h-4 w-4 text-[0px] [background:var(--url)_center_center_no-repeat] dark:invert&quot;
      style=&quot;--url: url(icons/info.svg);&quot;
    &gt;
      info
    &lt;/div&gt;
    &lt;span&gt;&lt;strong&gt;License&lt;/strong&gt;&lt;/span&gt;
  &lt;/div&gt;
  &lt;div class=&quot;pl-4&quot;&gt;&lt;p&gt;This content is licensed under a &lt;a rel=&quot;external&quot; href=&quot;https://creativecommons.org/licenses/by/4.0/&quot;&gt;Creative Commons Attribution 4.0 International license&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</content>

        
        
        <post-thumbnail><url>https://blog.museum-digital.org/2022/04/03/iiif-and-museum-digital/iiif-logo.png</url></post-thumbnail>
        
        
    </entry>
</feed>
