Author: Yusuf Rahimi

  • Delivery is part of your DAM, not something that happens after it

    Delivery is part of your DAM, not something that happens after it

    The DAM selection was thorough. Governance, metadata, workflow, integrations, all properly evaluated. Delivery was out of scope because the web team has a CDN.

    Eighteen months later the web team has built an image service. It resizes, converts formats, caches, and has a queue of bugs about invalidation. It is now a system nobody planned, nobody owns, and nobody documented, sitting between the DAM and every page.

    Short answer: if the DAM cannot deliver a correctly sized, correctly formatted image directly to a browser, somebody in your organisation will build the thing that does. That thing is a second system with its own storage, its own cache, and its own staleness bugs, and it is usually more expensive than the delivery capability you declined to evaluate. Put delivery in the selection criteria.

    A bar chart of page weight by asset source with a tall amber original bar and four descending cyan bars, overlaid by a load time line and a dashed budget rule

    What “delivery” has to cover

    Five capabilities. If the platform does not have them, you are building them.

    Resize on request. Any dimension, from a URL, without pre-generating variants. Not a fixed set of preset sizes chosen at configuration time, because the sizes you need change with every design refresh.

    Automatic format selection. Serve AVIF to browsers that support it, WebP to those that support that, JPEG to the rest, from one URL. AVIF support is broad enough now that this is a substantial and immediate payload reduction, and WebP covers essentially everything else. The MDN image format guide is the reference for what each format is actually good at.

    Automatic quality. Compression tuned per image rather than a global setting. A flat quality number is always wrong somewhere: too aggressive on a gradient, too generous on a flat graphic. Content-aware quality selection removes an entire category of manual tuning.

    Content-aware cropping. A 1:1 crop of a wide product shot should keep the product, not the geometric centre. Doing this by rule produces bad crops at volume; doing it by hand does not scale. Cloudinary bundles these three under automatic format, quality and gravity, with the cropping mechanics in resizing and cropping.

    Edge caching with sane invalidation. Derivatives cached close to users, and a versioned URL scheme so replacing a master produces a new address rather than requiring a purge across a content delivery network.

    Why this is a business number, not an engineering preference

    Image weight is usually the largest single contributor to Largest Contentful Paint on a content or commerce page, and LCP is the metric that most directly tracks perceived load speed.

    Two consequences that belong in the business case rather than the technical appendix:

    Bandwidth cost. You are paying to serve every byte. Get your current monthly image bytes from your CDN, model the reduction from automatic format and quality, and price it at your existing rate. This is a real number from an existing invoice, which puts it in the most credible benefit category in the business case.

    Conversion. Page speed affects conversion. State the mechanism, do not put a percentage in the case unless you can run the experiment yourself. Borrowed conversion statistics are the fastest way to lose a reviewer’s trust, and the effect is real enough that you do not need to inflate it.

    A responsive delivery ladder with one master card feeding nine derived output rectangles by parameter, three device outlines pointing at their rungs

    Responsive is the part that breaks stored variants

    This is the argument that settles the derived-versus-stored question on technical grounds rather than economic ones.

    A modern responsive page does not know what size image it needs until the browser knows its own viewport, its device pixel ratio, and the layout after CSS has run. The correct width might be 412 pixels, or 824, or 1236. Multiply that by every breakpoint, every density and every art-directed crop and the set of required derivatives is combinatorially large and not knowable in advance.

    Stored variants cannot serve that. You end up picking six sizes, serving the nearest larger one, and shipping between twenty and sixty percent more bytes than necessary on most devices.

    Derived delivery can, because the size is a parameter and the result is cached on first request. Responsive image delivery covers the mechanics along with the srcset and sizes generation. The important property is that the first request for an uncommon width is slightly slower and every subsequent one is a cache hit, so real traffic converges on cached almost immediately.

    What about the CDN we already have?

    Reasonable question, and the answer depends on which of two things your CDN does.

    A plain CDN caches and serves bytes. It does not resize, convert format, or crop. Put one in front of a DAM that only serves originals and you have fast delivery of oversized images, which is a smaller improvement than it sounds.

    An image CDN transforms on the way through. Cloudflare Images, imgix and ImageKit all do this well, and they are legitimate answers if your DAM genuinely cannot deliver.

    The trade-off is worth stating plainly rather than dismissing. A separate image CDN gives you a good transformation layer and a second system to operate, with its own origin configuration, its own cache semantics, and its own answer to the question of what happens when a master is replaced or a licence expires. That last one matters more than it looks: an expiry event in the DAM has to propagate to the image CDN, and that propagation is your problem to build and to test.

    Where the DAM and the delivery layer are the same platform, that class of problem does not exist, which is the same argument made from the architecture side in single source of truth is an architecture.

    Extreme macro of a printed halftone rosette on paper fibre under raking cyan light, degrading into amber blocky compression artefacts on the right third

    What to test in an evaluation

    Half a day, and it separates the field faster than any feature matrix.

    1. Upload one large photograph. Request it at five widths, in three formats, with two crop strategies, by editing the URL. Time to first byte on a cold request, and again on a warm one.
    2. Compare bytes against what your site currently serves for the same image at the same rendered size. That ratio is your bandwidth saving, measured rather than claimed.
    3. Replace the master. Confirm that existing references pick up the new version, that old versioned URLs still resolve, and that nothing required a manual purge.
    4. Check the cache headers the platform sets by default. Immutable derivatives should carry a long max-age. If they carry a short one, your cache hit rate will be poor and your costs high.
    5. Test a restricted asset. Confirm its delivery URL does not resolve without authorisation, using the mechanism in access control on delivery. Public-by-default delivery is a common misconfiguration and it belongs in the security review described in access control, SSO and audit trails.

    Accessibility travels with delivery

    One thing that gets separated from this discussion and should not: alt text is part of correct delivery, not a content afterthought.

    If the DAM holds a default description on the asset and the consuming system fetches it alongside the URL, alt text is present by default and only overridden where context demands it. If the DAM holds it and nobody fetches it, every consuming system reinvents it or omits it, and omission is the usual outcome. The WCAG overview covers the requirement, and the field ownership question is settled in who owns which record.

    Ask in every demo whether the delivery API returns the descriptive metadata alongside the asset. Surprisingly often the answer is no, and that single gap is why so many sites have empty alt attributes on images that were properly described upstream.

    The one-line version

    If the answer to “how does an image get from the DAM onto a page at the right size and format” is “the web team handles that”, you have not finished the evaluation. You have deferred a system.

    The API characteristics that make this work are in headless DAM, the patterns for wiring it up are in integration patterns for an enterprise DAM, and if delivery turns out to be your dominant requirement, alternatives to a traditional enterprise DAM is the more useful starting point than a classic DAM shortlist.

  • Migrating a million assets without losing provenance

    Migrating a million assets without losing provenance

    The migration plan says twelve weeks. Week one moves four hundred thousand files without incident and everybody relaxes. Week nine is still going, because somebody noticed that the folder names encoded the campaign, the campaign is not a field in the target system, and eleven months of context evaporated on the way across.

    Short answer: a DAM migration is a metadata project with a file copy attached, not the other way round. Most of what makes an asset useful lives outside the file, usually in folder paths, filenames, spreadsheets and people’s heads. Extract that first, map it explicitly, validate the mapping on a sample, and only then move bytes. And leave most of the library behind, because most of it is not worth the cost of bringing.

    An isometric mass migration: thousands of matte tiles on the left, a cyan transfer bridge with an inspection arch, ordered tiles on the right, and a few amber tiles face down with tags stripped

    Where the context actually lives

    Before you plan anything, go and look at where meaning is currently stored. In a typical enterprise estate it is in five places, and only one of them is the file.

    • Folder paths. Usually the richest source. /2025/Campaigns/AutumnRange/DE/Approved/ carries year, activity, campaign, market and status. That is five fields, encoded positionally, undocumented, and inconsistent after the third reorganisation.
    • Filenames. Version numbers, crop indicators, photographer initials, client codes. Also positional, also undocumented, also inconsistent.
    • Embedded metadata. IPTC and EXIF fields, where they survived. Check with ExifTool rather than assuming. Most production pipelines strip these on export, so coverage is usually far lower than people expect.
    • Side files and spreadsheets. The tracking sheet the studio maintains. Nearly always the best source of rights information, and nearly always in a shared drive nobody mentioned in the discovery workshop.
    • People. Which is not migratable, which is why the discovery interviews have to happen before anyone’s notice period starts.

    Write an extraction plan for each of the first four. The fifth is why you do this now rather than later.

    The sequence

    Nine steps. Skipping any of the first four is how twelve weeks becomes nine months.

    1. Inventory. Count distinct masters, not files. Hash everything and group by hash. The duplicate ratio you find is the first real number in the project and it is usually somewhere between 3:1 and 8:1. It also tells you how much of the migration you can simply not do.

    2. Profile. For each source of context, measure coverage. What percentage of assets have a parseable folder pattern, a usable filename convention, embedded metadata, a spreadsheet row. This determines the mapping strategy and it is a day of work.

    3. Decide what moves. The single most valuable decision in the project. Criteria that work in practice: accessed in the last two years, or referenced by a live placement, or carrying third-party rights, or part of the current brand system. Everything else stays where it is, in a read-only archive, reachable but not migrated.

    Expect this to eliminate somewhere between fifty and eighty percent of the library. That is not data loss, it is declining to pay to move things nobody will ever open. Everyone finds this uncomfortable and everyone who does it is glad afterwards.

    4. Map fields explicitly. Source expression to target field, one row per rule, written down and reviewed. Regular expressions over paths and filenames, lookups against spreadsheets, defaults for the rest. This artefact is the migration; the code is just an implementation of it.

    5. Dry run on a stratified sample. Two thousand assets chosen to cover every folder pattern you found, not two thousand at random. Random samples miss the weird corners, and the weird corners are the whole problem.

    6. Review the sample with the people who own the material. Not with the migration team. The cataloguers and brand managers will spot in ten minutes what an engineer cannot spot at all, because they know what the values are supposed to mean.

    7. Migrate in waves, grouped by source pattern rather than by volume. Each wave validates the mapping rules for that pattern before the next one runs.

    8. Reconcile every wave. Count in, count out, checksum match, required-field completeness. A wave that does not reconcile does not get signed off, and the next wave does not start.

    9. Cut over reads before writes. Point consumers at the new system while the old one is still writable, then close writes on the old system once traffic is stable. Reversing that order is how you end up with two live systems and a merge problem.

    A field mapping figure with mostly clean cyan one-to-one lines, three converging many-to-one lines, and two amber source slots with drop icons

    What gets silently lost

    Five things, and the word to notice is silently. None of these throws an error.

    Folder-encoded context, if you copy the tree as a tree instead of parsing it into fields. The most common single failure, and the most expensive, because it is only detected months later when search does not work.

    Version relationships. Which file superseded which. Usually encoded in filenames, usually discarded, and once gone it is unrecoverable because the information was never anywhere else.

    Usage history. Where an asset was published. Rarely captured anywhere and therefore rarely migrated, which matters the first time you need to recall something.

    Rights terms, if they lived in a spreadsheet rather than a field. This one has legal consequences, and it is worth doing manually for the licensed subset even if everything else is automated. The field model to migrate into is in rights and expiry as first-class asset data.

    Approval state. Often expressed as a folder called Approved, which is exactly the kind of thing a naive path copy turns into a directory nobody looks at.

    Do you migrate the derivatives?

    No. This is one of the few genuinely easy calls in the project.

    If your source library contains a master plus fourteen crops and format variants, migrate the master. In a platform where renditions are derived from a URL parameter rather than stored, the fourteen variants have no reason to exist on the far side, and the transformation reference covers what replaces them. You will reduce the volume to be moved by an order of magnitude and eliminate a whole class of “which crop is current” questions permanently.

    Two exceptions worth handling deliberately. Hand-retouched variants are not derivatives, they are separate masters, and they need identifying before you delete anything. And any derivative whose URL is referenced by a live external system needs a redirect or a replacement reference, which is the same problem as any URL change.

    For the mechanics of bringing material in at volume, the migration documentation covers bulk approaches, and the command line interface is generally the more practical tool than hand-rolled scripts for anything above a few thousand assets.

    A migration burndown chart with a cyan staircase line above a dotted linear plan, and one amber plateau where validation stalled

    How long does it actually take?

    Depends almost entirely on metadata quality, not on volume. Two useful reference shapes:

    Well-described library, consistent conventions, good embedded metadata. Six to ten weeks for a few hundred thousand assets, and most of that is validation rather than transfer.

    Inconsistent conventions, minimal embedded metadata, context in people’s heads. Four to nine months for the same volume, and the variance is entirely in how much manual cataloguing you accept versus how much you leave undescribed.

    The lever is step three. Every asset you decide not to migrate is an asset you do not have to describe, and describing is the expensive part. Teams that migrate everything spend the difference on cataloguing material nobody will search for.

    The thing that actually derails it

    Not technology. Scope creep dressed as quality improvement.

    Halfway through, somebody proposes fixing the taxonomy while we are in here. Then improving the descriptions. Then adding the fields we always wanted. Each is individually reasonable and collectively they turn a migration into a re-cataloguing programme with a migration attached, and the go-live date moves twice.

    Migrate to the schema you designed, with the data you have. Improve afterwards, as business as usual, against the metrics in designing a taxonomy people actually use. A live system with adequate metadata beats a perfect one that is still three months out, and the difference in adoption between those two outcomes is enormous.

    Before any of this, be sure you have decided what you are migrating away from and why. Why the shared drive stops working covers the diagnosis, headless DAM covers what you need from the target platform’s API to script any of this, and if the destination is still open, alternatives to a traditional enterprise DAM is worth reading before you commit. The foundation is in what enterprise DAM actually is.

  • Headless DAM: when the API is the product

    Headless DAM: when the API is the product

    Every DAM vendor has an API now. That sentence is true and almost entirely uninformative, because it covers both a system designed API-first and a system where someone exposed nine endpoints in 2021 to close a deal.

    The distinction is not marketing. It determines whether your integration project takes six weeks or six months, and whether the platform can serve channels that do not exist yet.

    Short answer: headless DAM means the API is the product and the web interface is one client of it, with no privileged access. The test is simple. Anything a user can do in the interface, you can do over the API, with the same permissions model and the same validation. If there is a gap, the API is a reporting layer with delusions, and every integration you build will eventually hit the edge of it.

    An orthographic schematic of a core block with an API port array feeding five consumer panels, with the space where a monolithic front end would sit left as an empty dashed outline

    Why this became the architecture rather than a preference

    Ten years ago the DAM was a destination. People logged in, browsed, downloaded, and took the file somewhere else. The interface was the product because the interface was where the work happened.

    That is no longer where the work happens. Assets are consumed by a commerce platform, a headless CMS, a mobile app, a partner portal, a print automation pipeline, an email service, and increasingly by agents assembling pages without a human in the loop. Every one of those is a machine reading a machine. None of them can use a login form.

    So the interface stopped being the product and became one consumer among many, usually not even the busiest one. A platform whose capabilities live primarily in its interface is a platform whose capabilities are unavailable to most of its actual traffic.

    The four questions

    Ask these in the technical evaluation. They are quick, they are answerable in a live session, and they separate the field fast.

    1. Is the interface built on the public API? Open the browser network tab, perform an action in the vendor’s own interface, and look at what it calls. If those are documented public endpoints, the API is real and it is exercised by the vendor’s own team every day. If they are private endpoints with a different auth scheme, you are getting a second-class API and it will lag the interface forever.

    2. Can you define and enforce schema over the API? Not just read and write field values, but define the fields, their types and their controlled lists, and have those validated on every write path. If validation lives only in the upload form, then every integration is a bypass and your data quality is a function of developer discipline.

    3. Is search a real query interface? Filtering by folder is not search. You want expressions over your own metadata fields, with boolean composition, sorting and pagination that works past the first thousand results. The Cloudinary Admin API exposes resource search as a queryable expression rather than a folder walk, which is the shape to look for.

    4. What is the SDK and documentation situation? An API you have to hand-roll HTTP against is an API that will be integrated once, badly, by whoever is available. Breadth matters here because you will not get to choose which language the next consuming team writes in. Cloudinary publishes SDKs across roughly seventeen languages and frameworks, which is at the upper end of the category and worth using as a benchmark when a vendor tells you their two SDKs are sufficient.

    An isometric matte cube with six machined sockets of different key shapes and six floating connector plugs, one of them amber and matching nothing

    Delivery is part of the API surface

    This is the part that gets separated in evaluations and should not be.

    In a classic DAM, retrieval means download. You call an endpoint, you get bytes, and then it is your problem: resize it, convert it, cache it, put it on a CDN, invalidate it when it changes. That is four systems and a cache invalidation bug waiting to happen.

    In an API-first media platform, the delivery URL itself is the interface. You express what you want as parameters and the correct derivative is produced and cached at the edge. The Cloudinary transformation reference is the full parameter vocabulary, and advanced URL delivery options covers the addressing rules.

    The practical consequence is worth stating plainly, because it is easy to read this as a convenience feature. When a rendition is a URL parameter, no second file exists. Nothing to store, nothing to keep in sync with the master, nothing to purge when the master changes, nothing to migrate. A new channel with a new aspect ratio is a string change, not a batch job. That is the difference discussed at more length in delivery is part of your DAM.

    What about agents?

    This is genuinely new and worth a paragraph rather than a section, because the hype exceeds the shipped reality in most places.

    More of the software that consumes your assets is now written by, or driven by, language models. That changes what “good API” means in one specific way: the model has to be able to work out how to use it from documentation alone, in one pass, without a human debugging its first three attempts.

    Practically that means predictable URL structure, documentation served as markdown rather than a client-rendered application, and machine-readable descriptions of what the platform can do. Cloudinary ships an LLM and MCP integration layer covering exactly this: a set of remote Model Context Protocol servers, an llms.txt, and a rules file that steers models toward syntactically correct transformation URLs rather than plausible-looking wrong ones.

    Whether that matters to you depends on how much of your integration work is now agent-assisted. For most enterprise teams the honest answer in 2026 is “some, growing”. It is not a reason to select a platform on its own. It is a reasonable tiebreak, and it is a decent proxy for whether the API was designed to be read by something that has never seen it before.

    A URL anatomy bar broken into eight labelled segments with callouts, and three preview rectangles of different aspect ratios fanning out below

    Authentication, because this is where pilots die

    Two things to confirm before you build anything.

    Server-side signing for writes. Any upload path that runs from a browser needs signed requests generated server-side, so credentials never reach the client. Signed uploads is the standard pattern and every serious platform has it. If a vendor suggests putting an API key in your front-end, that is a complete answer to the evaluation.

    Standards-based delegation for user-facing access. If people will access assets through your own applications, you want OAuth 2.0 with OpenID Connect for identity and JWT for token format, not a proprietary scheme. Proprietary auth is the single most reliable predictor of an integration that takes three times its estimate.

    When headless is the wrong call

    Two situations where an API-first platform is genuinely a worse fit, and it is worth naming them.

    Your primary users are non-technical and the interface is the workflow. If the brand team, the agencies and the regional marketers spend their day in the DAM itself, browsing, collecting and downloading, then interface quality is not a nice-to-have and you should weight it accordingly. Some API-first platforms have thin interfaces because their centre of gravity is elsewhere. That is a real trade-off, not a flaw.

    You have no engineering capacity. An API is only an asset if someone can use it. If the DAM will be run entirely by a marketing operations team with no developer support, a well-designed closed suite with pre-built connectors will serve you better than a superior API you cannot call. This is one of the honest splits in the platform comparison.

    For everyone else, the API is the part of the system that will still be load-bearing in eight years, long after the interface has been redesigned twice. Weight it accordingly, and see integration patterns for an enterprise DAM for what you will actually build on top of it. The wider argument for keeping one master addressable by everything is in single source of truth is an architecture, and if you are earlier than that, start with what enterprise DAM actually is.