Azure Files is Microsoft's managed file-share service: a share you mount over SMB or NFS like a file server, without running one. Teams use it to lift and shift Windows file servers, to share configuration and content between VMs and containers, for user profiles in virtual desktop deployments, and as shared storage for Linux applications and training jobs that expect a POSIX file system.
It looks simple from the client side, and most production problems come from decisions made at creation time: which billing model and media tier, which protocol, how identities are checked, and which network path clients take. Several of those are hard or impossible to change later. This article explains each decision from first principles, gives the limits that actually bind, and works through sizing a share. Limits are quoted from Microsoft's published scale targets as of September 2026; they change, so recheck them before a design review.
The resource model
There are two ways to own a share. A classic file share lives inside a storage account from the Microsoft.Storage provider, and the account determines the media tier, billing model and redundancy for every share in it; all resources in the account share its IOPS and throughput limits. Classic shares support SMB and NFS. The newer Microsoft.FileShares provider creates a share as a top-level resource with no storage account; it supports NFS only and uses the provisioned v2 billing model, and Microsoft recommends it for new NFS deployments. If you need SMB, you need a classic share.
Inside a share there are directories and files, as on any file server. Data can also be reached through the FileREST API, which is how tools such as AzCopy and Storage Explorer work, and how some management operations are performed on the data plane.
Media tiers and billing models
| Billing model | Account kind and SKUs | Max share size | Max IOPS / throughput per share |
|---|---|---|---|
| SSD provisioned v2 | FileStorage, PremiumV2_LRS / PremiumV2_ZRS | 256 TiB | 102,400 IOPS / 10,340 MiB/s, as provisioned |
| HDD provisioned v2 | FileStorage, StandardV2_LRS, _ZRS, _GRS, _GZRS | 256 TiB | 50,000 IOPS / 5,120 MiB/s, as provisioned |
| SSD provisioned v1 | FileStorage, Premium_LRS / Premium_ZRS | 100 TiB | 102,400 IOPS / 10,340 MiB/s, scaling with capacity |
| HDD pay-as-you-go | StorageV2, Standard_* | 100 TiB | 20,000 IOPS; throughput up to the account limit |
The billing model decides what you pay for. Provisioned v2 lets you set storage (in 1 GiB units, minimum 32 GiB), IOPS and throughput independently, and allows credit-based bursting above provisioned IOPS on a best-effort basis. Provisioned v1 ties IOPS and throughput to provisioned capacity, so the only way to get more performance is to buy more space. Pay-as-you-go charges for used storage plus transactions, which suits cold, rarely touched data and punishes chatty workloads with a transaction bill that is hard to predict.
Redundancy follows the media. SSD shares support LRS and ZRS only; geo-redundant options exist only on HDD, and Azure Files does not offer read access to the secondary region even on read-access SKUs. If you need a readable copy elsewhere, replicate it yourself or use a backup product that supports your protocol.
The per-file limits that surprise people
Share limits are generous; per-file limits are not. On HDD, a single file is capped at 1,000 IOPS and 60 MiB/s for reads and for writes, whatever the share is provisioned for. On SSD the per-file cap is 12,000 IOPS, with single-client throughput of roughly 3 GiB/s read and 2 GiB/s write over SMB and roughly 2 GiB/s read and 1.5 GiB/s write over NFS, and up to 10,240 MiB/s of multi-client reads. Every file and directory accepts at most 2,000 concurrent handles, and the root directory 10,000.
These limits shape designs. A single large log file, SQLite database or model checkpoint on an HDD share cannot go faster than 60 MiB/s even if the share has thousands of MiB/s provisioned, and 3,000 containers that all open one shared configuration file exceed the handle limit. Spread hot data across files, keep the number of simultaneous openers per file bounded, and put single-file hot spots on SSD.
Metadata is its own budget. Opening, closing and listing consume metadata IOPS, capped at 12,000 per share, or up to 35,000 on SSD with NFS or SMB with metadata caching, regardless of how many data IOPS are provisioned. Workloads with many small files, such as source trees, package caches and datasets of thumbnails, hit this ceiling long before they approach throughput limits.
SMB or NFS
| SMB shares | NFS shares | |
|---|---|---|
| Clients | Windows, Linux, macOS | Linux and UNIX only; not supported from Windows |
| Media | SSD or HDD | SSD only |
| Authentication | Kerberos identity or storage account key | None per user: network rules, then UID/GID permissions |
| Permissions | Share-level RBAC plus NTFS-style ACLs | POSIX mode bits, root squash; no NFS ACLs, 16 groups per user |
| Azure File Sync, Azure Backup | Supported | Not supported at the time of writing |
| Snapshots, soft delete | Supported | Supported |
One share speaks one protocol, and a Windows and a Linux client cannot use NFS and SMB against the same data, though SMB and NFS shares can sit in the same account. Pick SMB when Windows clients, per-user identity or file-server replacement is involved. Pick NFS for Linux workloads that need POSIX semantics, case-sensitive names, hard links or UID/GID permissions, accepting that access control is enforced at the network layer.
Identity and authorisation for SMB
An SMB share can authenticate users against one of three identity sources per storage account, all using Kerberos. On-premises AD DS requires clients to reach the domain controllers and identities to be synchronised to Microsoft Entra ID. Microsoft Entra Domain Services uses a managed domain in Azure that clients must be joined to. Microsoft Entra Kerberos lets Entra ID issue the tickets, so clients need no line of sight to a domain controller; it covers hybrid and cloud-only identities on Windows and, in preview, macOS, but not Linux users. For applications and Azure workloads, managed identities can also access SMB shares without keys.
Access then needs two independent grants. A share-level permission is an Azure RBAC role on the share or account, with roles such as Storage File Data SMB Share Reader, Contributor and Elevated Contributor, or a default share-level permission that applies to all authenticated identities. A file and directory permission is an ordinary Windows ACL on the item. Both must allow the operation. The layered model follows the same logic as the RBAC plus ACL design in Azure Data Lake Storage Gen2 and the policy concepts in cloud IAM.
The storage account key sits outside this model: whoever holds it has full access to every share in the account. Use it for initial ACL setup and break-glass only, keep it in a secret store, rotate it, and prefer identity-based mounts everywhere else.
Networking
SMB uses TCP port 445, which many ISPs and corporate networks block outbound, so mounting over the internet often fails for reasons unrelated to Azure. There are three endpoint options. The public endpoint can be restricted with the account firewall to virtual networks and IP ranges. A service endpoint admits traffic from chosen subnets at no extra charge. A private endpoint gives the account a private IP in your virtual network, reachable from peered networks and from on-premises over VPN or ExpressRoute, with private DNS resolving the account name to that IP; private endpoints and Private Link covers the DNS pattern in detail.
NFS has no user authentication, so Azure accepts NFS traffic only from a private endpoint, a restricted public endpoint, or VPN and ExpressRoute paths. Encryption in transit is supported for NFS using TLS, governed by a per-protocol "Require Encryption in Transit for NFS" setting, which the portal enables by default for new accounts but CLI, PowerShell and REST leave unset for backward compatibility. Check it explicitly in your templates.
# SMB 3.1.1 from Linux with a credentials file (root-only permissions on the file)
sudo mkdir -p /mnt/team
sudo mount -t cifs //acmefiles.file.core.windows.net/team /mnt/team \
-o vers=3.1.1,credentials=/etc/smbcredentials/acmefiles.cred,serverino,nosharesock,actimeo=30,dir_mode=0770,file_mode=0660
# NFSv4.1 (SSD share, reachable only through a private or service endpoint)
sudo mkdir -p /mnt/datasets
sudo mount -t nfs acmenfs.file.core.windows.net:/acmenfs/datasets /mnt/datasets \
-o vers=4,minorversion=1,sec=sys,nconnect=4The SMB options mirror Microsoft's documented Linux settings: serverino keeps inode numbers stable, nosharesock gives each mount its own connection, and actimeo=30 caches attributes for 30 seconds. nconnect=4 opens several TCP connections per NFS mount, which raises per-client throughput.
Worked example: a shared training dataset
Sixteen Linux GPU nodes read a 5 TiB image dataset of about 2.5 million files, averaging 2 MiB. The data loader needs about 150 MiB/s per node, so 2,400 MiB/s in aggregate, and each epoch opens every file once. The Linux nodes want POSIX semantics, so the share is NFS, and NFS rules out HDD immediately because it is SSD-only.
With SSD provisioned v2: provision 6 TiB of storage for growth, 3,000 MiB/s of throughput for headroom, and IOPS from the I/O pattern. At 2 MiB per file and 2,400 MiB/s, the job reads about 1,200 files per second, each needing an open, reads and a close. That is well under the 35,000 metadata IOPS ceiling, but a dataset of 20 KiB thumbnails at the same throughput would need over 100,000 opens per second and would hit it first. For small-file datasets, pack samples into large shard files such as tar or record formats. Throughput per file is not a concern here because reads are spread across millions of files.
# SSD provisioned v2 account: FileStorage kind, PremiumV2 SKU, zone-redundant
az storage account create -g rg-ml -n acmenfs -l westeurope \
--kind FileStorage --sku PremiumV2_ZRS
# NFS share with storage, IOPS and throughput provisioned independently
az storage share-rm create -g rg-ml --storage-account acmenfs -n datasets \
--enabled-protocols NFS --root-squash RootSquash \
--quota 6144 --provisioned-iops 12000 --provisioned-bandwidth-mibps 1600
# Later: raise throughput for a training campaign, lower it afterwards
az storage share-rm update -g rg-ml --storage-account acmenfs -n datasets \
--provisioned-bandwidth-mibps 3000Because provisioned v2 separates throughput from capacity, you can raise throughput for a training campaign and lower it afterwards instead of buying capacity you do not need. Measure actual usage from the share's metrics before settling. If the dataset is read-only and fits object-storage access patterns, compare against reading shards directly from blob storage; object storage architecture explains where each model wins.
Data protection and operations
- Snapshots. Share snapshots are read-only, point-in-time copies, up to 200 per share. Schedule them for accidental-deletion recovery, but remember they live in the same account and are not a backup against account-level loss.
- Soft delete. Enable share soft delete so a deleted share can be restored within the retention window.
- Azure File Sync (SMB only) caches a share on Windows Servers on-premises, with cloud tiering keeping hot files local. It suits branch offices; it is not a replication mechanism for NFS.
- Monitoring. Alert on throttling and on transactions by response type, and watch metadata IOPS as well as data IOPS and throughput against provisioned values.
- Resource locks. Put a delete lock on production accounts; one mistaken deletion removes every share in the account.
Failure modes
- Port 445 blocked. Mounts time out from laptops and on-premises networks. Route through VPN or ExpressRoute to a private endpoint instead of opening 445 to the internet.
- Wrong billing model locked in. Account kind and media tier are set at creation. Moving from HDD to SSD, or pay-as-you-go to provisioned, means a new account and a data copy.
- One hot file. A shared log or database file on HDD stalls at the 60 MiB/s per-file cap while share metrics look idle. Split it or move it to SSD.
- Handle exhaustion. Thousands of clients holding one file or directory open hit the 2,000-handle limit and get open failures. Close handles promptly and fan out.
- Kerberos and DNS drift. Identity mounts fail when the private DNS zone or domain configuration is inconsistent. Test name resolution from each client network.
- NFS permission surprises. UIDs differ across images, or users belong to more than 16 groups, and access fails. Standardise UIDs and GIDs across clients.
What to do next
- Write down protocol, client operating systems, identity source, peak throughput, metadata rate and largest single-file rate for your workload before creating anything.
- Choose media and billing model from that list, preferring provisioned v2 for predictable cost and independent throughput.
- Create the account or share with a private endpoint and private DNS, and verify from each client network that the name resolves privately.
- For SMB, enable one identity source, assign share-level roles and ACLs, then keep the account key in a vault for break-glass use.
- For NFS, enable encryption in transit explicitly in your templates, enable root squash and standardise UIDs and GIDs.
- Enable snapshots, soft delete and a resource lock, and set alerts on throttling and metadata IOPS.
- Load-test with the real file sizes and client count, then adjust provisioned IOPS and throughput to measured peaks plus headroom.