Back to Blog
·VerseBlocks

Where generated documents should live in Dataverse

DataverseDocument GenerationCost ManagementPower Platform

Every document generation flow ends the same unglamorous way. Something has to write the output somewhere. A quote, a contract, a statement of work generated off a Dataverse record has three realistic homes. A file column on the record itself, the Notes area backed by the annotation table, or a SharePoint library wired up through Dataverse document management. Most teams never actually choose between these. Whoever built the first flow picked whatever was easiest to configure in the designer that afternoon, and that choice quietly became the architecture.

That choice is a cost decision and a security decision, made at the same time, and the two don't always agree. The option that looks cheapest on the monthly capacity bill is often the same one that doesn't carry Dataverse's row-level security to where the document ends up. Get this wrong on a record restricted to one team or business unit, and the restriction simply doesn't apply to the copy sitting in the new location.

The three places a generated document can land

A Dataverse file column defaults to a 32 MB maximum, or 32,768 KB, per Microsoft's field types documentation. You can raise that through the UI designer up to 131 MB, and once the column is saved you can't change the ceiling again. Push through the API instead of the UI, and the limit jumps to 10 GB, though Microsoft's file column data documentation requires chunked requests to get there, with a single request capped at 128 MB and a recommended chunk size of 4 MB. Structurally, the file itself sits in a separate FileAttachment table linked to the record, and Microsoft's capacity documentation is explicit that file columns consume File capacity, not Database capacity.

Notes and attachments run through the older annotation table. The default upload ceiling there is 5 MB, controlled by the Organization.MaxUploadFileSize setting, and Microsoft's attachment documentation puts the configurable maximum at roughly 125 MB. They also consume File capacity, though Microsoft's capacity documentation describes notes and attachments as moving from database to file storage, so depending on when your environment picked up that change, older attachments may still be billing against a different meter than new ones.

SharePoint document management works differently again. Turn it on for a table, and Dataverse creates document location records that point to a SharePoint library or folder, exposed through the SharePointDocumentLocation table. Microsoft's setup documentation confirms those bytes are physically stored on SharePoint Online servers, not in Dataverse, and the storage bill goes to SharePoint rather than to your Dataverse capacity meters. This only works cleanly on one-to-many relationships. Microsoft's own troubleshooting documentation says many-to-many relationships prevent documents from being listed at all, and libraries start throttling once you pass 5,000 documents.

What identical bytes cost in each capacity meter

Dataverse enforces three separate storage meters, Database, File, and Log, and Microsoft's capacity documentation confirms a default environment ships with 3 GB of each of the first two and 1 GB of the third. They are not priced alike. Microsoft's pay-as-you-go meters documentation, updated on 22 September 2026, puts Dataverse database storage at $48 per GB per month, file storage at $2.40, and log storage at $12, with the first gigabyte of database and the first gigabyte of file included per environment and log billed from the first byte. Buying prepaid capacity add-ons instead works out cheaper per gigabyte than the pay-as-you-go meters, so the figure that lands on your bill depends on which way you buy. The ratio between the meters holds either way. Database capacity costs twenty times what file capacity costs for identical bytes.

Run that against a real volume. A hundred gigabytes of generated PDFs bills as ninety-nine once each environment's included gigabyte comes off. In File capacity that comes to about $238 a month. Counted as Database capacity, the same bytes cost about $4,752, purely because of which meter they happened to land in.

That split happens to teams that never intended it, and it happens for a documented reason. Organisations running Microsoft's BYOK, or bring-your-own-key, model get a different storage path entirely. The file column documentation says plainly that for on-premises or BYOK environments, files and images are stored in Dataverse relational storage rather than file blob storage, and the file size ceiling drops to 128 MB per file regardless of what the column allows elsewhere. Turn on customer-managed encryption for compliance reasons, and every generated document a file column holds starts billing at the Database rate rather than the File rate, without anyone touching a size limit or a retention setting.

SharePoint's virtual table and the row-level security gap

The Documents grid that appears on a record once SharePoint integration is switched on is rendered from a virtual table, which Microsoft's troubleshooting documentation for document management confirms directly. Microsoft's own documentation on virtual tables states plainly that virtual tables are organization owned and do not support the row-level Dataverse security concepts. Field-level security doesn't apply to them either, and the row-level filtering that governs who can see a user-owned record has no equivalent here.

Take a case restricted to one support team through a business unit or a sharing rule. A resolution letter generated from that case and filed into its SharePoint folder doesn't carry that restriction with it. Anyone Dataverse itself would block from opening the case can, per Microsoft's own documentation, access the document directly on the SharePoint server if their SharePoint permissions allow it. Access control for that document now sits in a second system, one that somebody has to configure and maintain on purpose, because Dataverse won't do it automatically.

Azure Blob Storage has no first-party path

For a team that wants file column data sitting in its own Azure Storage account, under its own subscription, Microsoft's documentation describes no way to do that, not as a shipped feature and not as a preview. Architects proposing it as an option should say so plainly instead of presenting a workaround as a capability that ships.

What does exist is customer-managed keys, and it solves a different problem. CMK, through Azure Key Vault or an on-premises HSM, encrypts data that's already sitting inside Dataverse. It doesn't move that data anywhere, and Microsoft's capacity documentation notes the encryption only covers Dataverse data; connector settings and everything outside Dataverse are still encrypted with Microsoft-managed keys. Turning CMK on for a document-heavy environment can push file column data into Database capacity at the same time, the opposite of the result most teams want when they adopt it.

One more gap is worth naming plainly. Microsoft's documentation doesn't specify what happens to file column, notes, or attachment data during backup and restore operations. If a disaster recovery plan depends on knowing exactly how generated documents survive a restore, that detail isn't published, so confirm it directly with Microsoft rather than assume file data behaves like the relational data around it.

For a document that has to carry the same restriction as the record it came from, a file column is the right default. It bills against File capacity at the cheap rate as long as customer-managed keys aren't in play, and it inherits Dataverse's row-level security because the file is stored as part of the record itself rather than in a separate system. It also doesn't require anyone to build a second access-control system to match the first. The size ceiling, 131 MB through the UI or 10 GB through the API with chunking, covers nearly every generated document that isn't a video file. Save SharePoint document management for cases where the volume or the collaboration need earns it, and if the record involved is restricted, build SharePoint's own permissions on purpose rather than assuming Dataverse handed them over for free.