To Choose or Not to Choose – The Lakehouse and Warehouse in Microsoft Fabric

February 29, 2024
20 min read

To Choose or Not to Choose – The Lakehouse and Warehouse in Microsoft Fabric

Microsoft Fabric is a new centralized, AI-powered cloud data platform hosted by Microsoft. It combines several services of the existing Azure Data Platform – such as Azure Data Factory – with Power BI, while also introducing new services (figure 2). It’s tempting to compare Microsoft Fabric with Azure Synapse Analytics since Synapse also bundles different services together, but Fabric is so much more. In contract with Synapse, Fabric is a software-as-a-service (SaaS) platform providing you with many low-code to no-code data services.

This doesn’t mean no code has to be written. On the contrary, in this article we’re going to focus on two services of Fabric: the lakehouse and the warehouse. The first one is part of the Data Engineering experience in Fabric, while the latter is part of the Data Warehousing experience. Both require code to be written to create any sort of artifact. In the warehouse we can use T-SQL to create tables, load data into them and do any kind of transformation. In the lakehouse, we use notebooks to work with data, typically in languages such as PySpark or Spark SQL.

A diagram displaying all available services in Fabric, with the OneLake storage layer beneath them.
Figure 1: High-level overview of the services in Microsoft Fabric | Used with permission from Microsoft.

For an overview of all the available services/experiences in Fabric, check out my article Microsoft Fabric Personas.

If we can create tables and work with data in both the lakehouse or the warehouse, how do we choose between the two? When would you use one or the other? The answer is – as always – it depends. In this article, I'm going to present you with the advantages and disadvantages of each service and everything else you might take into consideration to make an informed decision about which service might be best suited for your use case.

Microsoft Fabric Behind the Scenes

Let me first tell you how Microsoft Fabric works. For example, how is data stored in Microsoft Fabric? The answer is quite simple: everything is stored in the OneLake storage layer. This is a logical data lake build on top of Azure Data Lake Storage Gen2. It acts as a wrapper around this storage. Microsoft commonly refers to OneLake as “OneLake is the OneDrive for your data.” This means that in reality you might be using one or more Azure Data Lake storage accounts depending on your set-up and which regions you use, but you will perceive it as one single storage. As mentioned before, Fabric tries to centralize as much as it can. A benefit of this is that one service can read data stored by another service. For example, if you create a table in a lakehouse, you can query this table from a warehouse. This is known as the OneCopy feature.

Another interesting fact about storage is that all tables you create in the warehouse and in the lakehouse are delta tables. Delta is an open-source format that applies a transaction log on top of Parquet files. In other words, all table data is stored in Parquet files (these are well-compressed files where data is stored using a columnstore format). However, Parquet files are immutable, which means they cannot be updated after they are written to storage. Every time you insert, update or delete a record in a table, a new Parquet file has to be written out. The delta format manages a transaction log alongside all those Parquet files, guaranteeing ACID compliance just like in relational databases. In short, thanks to the delta format, we can use Parquet files to store our data but it all works similar to a regular relational database such as SQL Server.

When you look at how a table is stored in OneLake, you can see two folders (figure 2):

Screenshot of file folders of a delta table in the storage layer. One folder for the transaction log, one folder for the Parquet files
Figure 2: Delta table with transaction log and Parquet files. | Image created by Koen Verbeeck

In the _delta_log folder (figure 3) you can see the whole transaction log of the table:

Screenshot of a transaction log of a delta table, showing 8 different transactions.
Figure 3: Transaction log of the Delta table | Image created by Koen Verbeeck

In the other folder (figure 4) you can see a whole bunch of Parquet files. They contain the data of the table through various points in time (new files can be created after each transaction).

Screenshot of a folder with a bunch of Parquet files. Displayed is also (second row) a deletion vector file.
Figure 4: The different Parquet files of a Delta table | Image created by Koen Verbeeck

The folder also contains a deletion vector, which is an optimization technique to handle deletes more efficiently.

Now you know how data is stored, but how is the compute managed in Fabric? The driving force behind everything in Fabric are the capacities. A capacity is a compute resource and is designated with a scale. The lowest capacity is an F2, the next one is F4, then F8 all the way up to F2048. Every time something wants to use compute, the capacity is used. It doesn’t matter if it is a warehouse, a data factory pipeline, or a real-time stream, it all uses the same capacity.

In the Microsoft Fabric portal (which is the same as the one used for Power BI), you can create workspaces and you can assign a capacity to that workspace (figure 5).

Screenshot showing the list of options when assigning a capacity to a workspace.
Figure 5: Assigning a Fabric capacity to a workspace | Used with permission from Microsoft.

At the time of writing (February 2024), there’s also a free trial of Fabric available. This trial capacity is equivalent with an F64. There are three methods of purchasing Microsoft Fabric:

  • You provision an F-SKU through the Azure Portal. This capacity can be paused. You will be billed for the time the capacity is running. The capacity can be scaled up and down when needed. This is pay-as-you-go pricing. You can learn more about this option in my article What are Capacities in Microsoft Fabric?
  • You can also buy a reserved capacity. You pay for a reserved number of CU (capacity units) up front. Say for example that you buy an F4 with reserved pricing for the whole year. But the capacity that you’ve been running the whole time is an F8. This means that 4 capacity units will be subtracted from the total of 8, so you only pay for 4 capacity units with pay-as-you-go pricing. If you don’t scale up and only use F4 for the whole year, you’d pay nothing extra. So think of the reserved capacity units as some sort of “voucher” that you can use to get capacity units at a lower cost. More info can be found in the documentation.
  • The last option is to buy Power BI Premium. With Power BI Premium, you get a fixed capacity that you can assign to workspaces, and you also get all of the Fabric capabilities with it. A P1 Premium capacity is equivalent with an F64, a P2 with an F128 and so on.

The table in figure 6 gives an overview of the SKUs and indicative prices for the pay-as-you-go options:

Screenshot of a table with the capacities from F2 till F2048 along with prices in dollars.
Figure 6: Price overview for Fabric

A P1 Premium capacity is around $5,000, so it is considerably cheaper than an F64 if you would keep it running all the time. Only consider the pay-as-you-go option if you can pause the capacity for longer periods of time.

To conclude this section: every compute service in Microsoft uses the OneLake storage layer to store data (and in the case of the warehouse and the lakehouse it’s both delta tables), and they also use the same capacity for compute resources. So if both compute and storage are the same, what is the difference between the lakehouse and the warehouse?

The Warehouse Versus the Lakehouse

The Warehouse

Even though the storage layer is completely different from SQL Server, a lot of effort has been made to make the warehouse have the look and feel of the old ‘n trustworthy relational database. When you create a warehouse in Fabric, you’ll be taken to the screen shown in figure 7.

the Fabric warehouse editor in the browser. On the left there’s an explorer, on the right a data preview pane.
Figure 7: The Warehouse editor in Fabric | Used with permission from Microsoft.

You can see familiar objects from SQL Server present: the dbo schema, tables, views, functions, and stored procedures. Working with the warehouse in Fabric is very similar to “traditional data warehousing” using a database like SQL Server or Azure SQL Database. Once data has been loaded into tables, you will write (mostly) the same T-SQL as we’ve been doing for the past years/decades.

However, not everything is supported (yet). For example, the TRUNCATE TABLE statement isn’t available, as well as identity columns, temporary tables, and the MERGE statement. Hopefully many limitations will be lifted in the future. You can find an overview of the current limitations in the documentation. Primary keys, foreign keys and unique keys are supported, but at the moment they’re not enforced. It can still be useful to create them, as it allows the query engine to create more optimal plans and because some BI tools use constraints to automatically create relationships. More info can be found here.

Ingesting Data

Before we start writing SQL, we must ingest data first. There are several options available:

  • Data Pipelines. These are very similar to Azure Data Factory pipelines. They are a low-code to no-code experience for copying data to a destination (in this case the warehouse), or for orchestrating various other tasks. You can schedule pipelines (figure 8) for automatic data retrieval.
Image of a sample pipeline in Fabric consisting of 4 activities: get metadata, copy data, run stored proc, and send alert.
Figure 8: Sample pipeline in Fabric | Used with permission from Microsoft.
  • Dataflows. These are very similar to Power BI dataflows. Both use the Power Query engine, but dataflows in Fabric can write to several possible destinations. Unlike data pipelines, you can actually see the data you’re working with, making them ideal for “citizen developers.” You can define a refresh schedule for a dataflow, or you can trigger them from a pipeline.
Screenshot of an example of a Fabric Dataflow, with data in preview.
Figure 9: Fabric Dataflow with sample data | Used with permission from Microsoft.
  • COPY T-SQL statement. With the COPY INTO statement, data stored in Parquet files or in CSV files can be loaded into a warehouse table. Currently only Azure Data Lake Storage or Blob accounts are supported as an external location.
  • Selecting data from other workspace sources. As mentioned before, thanks to the OneCopy principle, data can be read from other warehouses or lakehouses. You can use the 3-part naming convention database.schema.table to reference a table in another warehouse/lakehouse. Using SQL statements such as CREATE TABLE AS SELECT (CTAS), INSERT INTO or SELECT INTO, you can retrieve data from other sources (or from within the same warehouse), transform it and then write the results to a table.

People who have been working with the SQL Server platform or with the Azure Data Platform should be familiar with most of the options available to ingest data. In fact, existing code should be able to be migrated to the Fabric ecosystem, keeping in mind that there are still some limitations to the T-SQL supported in Fabric.

For more information about the data ingestion options, check out the documentation or my article, Microsoft Fabric Data Ingestion Methods and Tools.

Transactions

Thanks to the transaction log of the delta tables, but also thanks to an internally managed transaction log, the warehouse is fully ACID-compliant. Only the snapshot isolation level is supported. Transactions that span across different databases in the same workspace are supported.

You can find more information about transactions in the warehouse here.

Security

The same access controls that exist in SQL Server are available in the Fabric warehouse as well. You can use GRANT and DENY for granular object or column level security for example. For more fine-grained access, you can use row-level security or data masking. The documentation page Security for data warehousing in Microsoft Fabric has a good overview of all possible security measures. Another method is “sharing” a warehouse (figure 10), which is interesting when you want only a specific warehouse to be visible to someone.

The sharing window for a warehouse in Fabric. You can change settings for additional permissions and enter e-mail addresses for adding people, just like in OneDrive.
Figure 10: Sharing a Fabric warehouse | Used with permission from Microsoft.

Conclusion About the Warehouse

Even though the storage layer is completely different than SQL Server, the Fabric warehouse is very similar to its on-premises counterpart. You can write the same T-SQL – albeit with some restrictions – and use the same security and transactions controls. The primary developer skill set is still T-SQL, combined with maybe Pipelines or Dataflows for ingesting data or for orchestrating the ETL flow. People who have been building data warehouses with relational databases should have little trouble working with the Fabric warehouse.

The Lakehouse

Together with the rise (and fall?) of big data, the data lake made its introduction years ago. Because storage is cheap, you can put terabytes of data in your data lake and figure out what to do with it later (schema-on-read vs schema-on-write). Decoupling storage from compute (in traditional databases the storage is proprietary and included into the database engine) had the advantage that you could scale your storage separately and choose which compute service suits you best. Turns out querying all those files – without any predefined structure – is quite hard. To bring together the strengths of the data lake and the traditional data warehouse, the data lakehouse was introduced. Thanks to the delta format, you can treat Parquet files like regular tables and have a transaction log associated with them. But they’re still files on a file system, so you can keep on scaling that storage.

Fabric also has a lakehouse service and as mentioned before, data is kept in the OneLake storage layer.

Tables & Files

A big difference with the warehouse is that a lakehouse can have both tables and files. Tables can be delta tables, but other types of tables are supported as well (for example csv or Parquet; a delta table is indicated with a small black triangle, as seen in figure 11). Tables can be either managed (Spark takes care of the metadata and the data) or unmanaged (Spark only takes care of the metadata). You can read a good overview of the different types in the article Working with tables in Microsoft Fabric Lakehouse – Everything you need to know!

Screenshot of a lakehouse with a table and files section. The table named nyctaxi_raw is selected, and its data is shown in a preview in the pane on the right.
Figure 11: A lakehouse with both tables and files | Used with permission from Microsoft.

The files section shows the “unmanaged” section of the lakehouse. This can be any file type. When you click on a folder in the explorer pane,  you’ll see all of the files listed in the preview pane on the right.

a folder is selected in the files section of the explorer. The files in that folder are shown in the preview pane
Figure 12: File preview in the lakehouse. | Used with permission from Microsoft.

A nice feature of Fabric is the ability to create shortcuts (figure 13). With a shortcut, you can link to data that is stored in an external location, such as an Azure Blob container, an S3 bucket or maybe files in another lakehouse.

the screen you get when creating a new shortcut. You can choose between OneLake, S3, or Azure Data Lake Storage
Figure 13: Dialog for creating a new shortcut. | Used with permission from Microsoft.

 

A shortcut makes the data or file visible in the lakehouse, but it doesn’t take a physical copy. The data remains at the source and is only loaded when the shortcut is queried. Shortcuts are a method of simplifying ETL and minimizing the amount of data that needs to be copied between systems. You can create shortcuts in the file section, or you can create them in the table section. When an object is a shortcut, a little paperclip icon will be shown.

Ingesting Data

Like in the warehouse, there are a couple of ways to get data into the lakehouse.

  • Pipelines and Dataflows. Exactly the same as in the warehouse, but now with a lakehouse as the destination.
  • The lakehouse interface. When you right-click on a file or folder, you can choose to load its data to a (delta) table. This is fine for a one-shot analysis or a demo/proof-of-concept, but in real-life scenarios you might want to opt for an ingestion method that can be automated.
the context menu to load a file to a table in the lakehouse
Figure 14: Load data manually to a table. | Used with permission from Microsoft.
  • Notebooks. The main method to work with a lakehouse is notebooks (figure 15). They allow you to write Spark code (PySpark, Spark SQL, Scale or SparkR). You can connect to any data source that is supported by any of the languages (you can load modules for extra functionality) and load the data to the lakehouse. In a notebook, you can control if data ends up in a delta table or another type of table, or if the table is managed or unmanaged.
a notebook with PySpark code that reads data from a blob container into a data frame
Figure 15: A notebook reading data from Azure Open Datasets with PySpark into a data frame. | Image created by Koen Verbeeck.
  • Real-time streaming with event streams. Event streams are a low-code solution to fetch real-time data, apply rules to it and push it to one or more destinations. A lakehouse is one of the possible destinations.
an event stream fetching data from a sample real-time data stream, pushing the data to a lakehouse
Figure 16: A sample event stream in Fabric. | Used with permission from Microsoft.

Querying Data

Besides ingesting data, with notebooks you can also pull data into data frames, do transformations on that data and even visualize it using many of the available Python libraries. You can use Pandas data frames if you want, or use Spark SQL to write SQL queries on top of your data. Since you’re using notebooks, you can even go further and make machine learning models and do data science experiments.

a notebook cell containing pyspark code
Figure 17: Notebook working with predictions. | Used with permission from Microsoft.

Important to note is that when you create a lakehouse, a SQL analytics endpoint is automatically created. This endpoint allows you to write T-SQL statements on top of the tables in the lakehouse, but it is read-only. This version of SQL is pretty much the same as the one you use in the warehouse, so it is a bit different from the Spark SQL you use in the notebooks. When you’re in the lakehouse, you can switch to the SQL endpoint in the top right corner (figure 18).

Switch from Lakehouse to SQL analytics endpoint
Figure 18: Switch from Lakehouse to SQL analytics endpoint. | Used with permission from Microsoft.

The SQL analytics endpoint (figure 19) resembles the warehouse explorer:

the SQL analytics endpoint of a lakehouse. On the left there’s an object explorer, similar to the warehouse. On the right is the data preview pane.
Figure 19: the SQL analytics endpoint of a lakehouse | Used with permission from Microsoft.

You can write T-SQL statements just like in the warehouse (but only read-only queries, figure 20):

a T-SQL query executed on a lakehouse. At the bottom the result grid is shown.
Figure 20: A T-SQL Query executed on a lakehouse | Used with permission from Microsoft.

The SQL endpoint is in fact treated as similar to the warehouse in the official documentation, as explained in the article Better together: the lakehouse and warehouse.

Transactions

The SQL endpoint has the same transaction support as the warehouse, but for read-only queries. This means, for example, that if a table has new rows added by another transaction (from a notebook), they are not included in any open transaction of running queries on the endpoint.

In theory the lakehouse supports ACID transactions because there’s a transaction log created by the delta layer. However, since it is completely open, no-one is stopping you from connecting to the OneLake storage layer and randomly deleting Parquet files from the table. This means consistency cannot be guaranteed (an interesting discussion about this topic is presented in the blog post ACID Transaction in Fabric?, and also check out the accompanying Twitter discussion).

Security

Again, the SQL analytics endpoint follows the warehouse closely. When it comes to security, the endpoint supports the same features: object and row-level security is available. However, there are no such security features when working with Spark. Security is mainly defined through workspace roles and lakehouse sharing.

Conclusion About Lakehouse

The main point I’m trying to make about the lakehouse is that it is a different beast than the warehouse. You can use notebooks to write code in various languages (PySpark, Spark SQL, Scala, SparkR and Java) and there are more possible use cases in the lakehouse, such as machine learning, data science and data visualization.

Each lakehouse comes with a SQL analytics endpoint, which you can use to write T-SQL on the lakehouse tables. The SQL endpoint shares the same features as the warehouse but is read-only.

Choosing Between the Two

We’re at the end of this article and hopefully you now have a good idea which features the warehouse and the lakehouse brings. When you need to decide which service you want to use when building your data platform in Fabric, you can ask yourself any of the following questions:

  • What are the skills of my current team? If you have a seasoned data warehouse team that has been building data warehouses in databases like SQL Server for years (and thus they have good SQL skills), you might want to opt for the warehouse (typical job titles are BI Developer, Analytics Engineer, ETL/data warehouse developer, data engineer). If on the other hand most people on the team have Python skills, the lakehouse might be a better option (typical job titles are data engineer and data scientist).
  • Do I need to migrate existing solutions? If you have data warehouses that need to be migrated (for example from SQL Server, Azure SQL DB or Synapse Analytics), the warehouse might be the easiest option since most of the code can be migrated without too much hassle (don’t forget to check the T-SQL limitations in Fabric!). If you need to migrate solutions from Databricks, the lakehouse is the better option.
  • Do you need to work with unstructured data? If you need to work with unstructured or semi-structured data, such as json files, images, video, audio and so on, then lakehouse is your choice.
  • Do you need to support other use cases besides just data warehousing? For example, if you want real-time data or machine learning models, the lakehouse will be a better fit.
  • What are your transaction and security requirements? If you have strict requirements about permissions, such as row-level security, and strict transaction requirements, the warehouse is probably the best options. Skills from SQL Server can easily be reused. However, the SQL analytics endpoint of the lakehouse supports the same features.

You can find a good overview of the differences between the warehouse and the lakehouse (and other services such as Power BI Datamarts and KQL databases) in the documentation

However, the main question you might need to ask yourself is: “Do I really need to choose?” You can perfectly combine both services in one single data platform. For example, you can use the medallion architecture where the bronze and silver layer are implemented in a lakehouse (or multiple lakehouses), and the gold layer in a warehouse. This idea is entertained in the blog post Fabric: Lakehouse or Data Warehouse? by Sam Debruyn.

As I stated in the introduction: the answer is it depends.

Koen Verbeeck

Koen Verbeeck

Koen Verbeeck is a seasoned business intelligence consultant working at AE in Belgium. He has over a decade of experience in the Microsoft Data Platform, both on-premises as in Azure. Koen has helped clients in different types of industries to get better and quicker insights in their data. He holds several certifications, among which the Azure Data Engineer cert. He’s a prolific writer, having published over 250 articles on different websites and hundreds of blog posts at sqlkover.com. He has spoken at various conferences, both local and international. For his efforts, Koen has been awarded with the Microsoft MVP data platform award for many years.