The next posts in this series focus on optimizing BizTalk Server 2013 R2 after installation. These recommendations help you improve performance and increase resilience. Apply them after you install and configure BizTalk Server.
📝 One-Minute Brief
Split BizTalk workloads across dedicated hosts (including 32-bit where required), consider High Performance power mode when Balanced hurts throughput, and enable “text in row” on key MessageBox tables for small-message scenarios.
Configure the host and Host instances
Why hosts matter
In every new BizTalk environment, you should create and configure hosts, host instances, and adapter handlers. BizTalk hosts give you flexibility and isolation. As a result, you can scale and manage workloads more predictably.
One of the best practices is to create dedicated logical hosts to specific functionality, such as message reception, message sending, or orchestration processing.
Default hosts created during configuration
By default, BizTalk creates two hosts and host instances:
- BizTalkServerApplication: BizTalk uses this host for most processing by default. It acts as the default send and receive handler for installed adapters (except HTTP, SOAP, and isolated WCF receive handlers). It also runs orchestrations and tracking.

- BizTalkServerIsolatedHost: BizTalk uses this host for HTTP, SOAP, and isolated WCF receive handlers (BasicHttp, CustomIsolated, WebHttp, WSHttp).

Best practice: split by function (and trust level)
Although BizTalk can run everything in a single host, you should separate hosts by responsibility. This approach improves security boundaries and operational control. In particular, separate:
- Receiving
- Sending
- Processing (orchestrations)
- Tracking
Also, separate trusted and non-trusted workloads when you can. That way, you limit blast radius and simplify governance.
What do you gain by separating hosts
Splitting hosts gives you several concrete benefits:
- Each host instance gets its own resources (memory, handles, threads).
- Multiple hosts reduce contention in the MessageBox queue tables.
- BizTalk applies throttling at the host level, so you can tune behavior per host.
- Each host runs under a dedicated Windows identity, which strengthens security.
What do you risk if you create too many hosts?
More hosts can help, but too many host instances increase overhead. Each host instance runs as a Windows service (BTSNTSvc.exe or BTSNTSvc64.exe). Therefore, it consumes CPU, memory, and threads. It also increases the load on the MessageBox. Keep the design simple, then expand only when measurements justify it.
The following figure provides a general overview of the relationship among servers, hosts, and host instances; however, it is not intended to be a best practice. This architecture will depend on many factors and will change from client to client:

Typical baseline (and the 32-bit requirement)
Many people recommend “at least four” host instances: Receive, Send, Processing, and Tracking. That baseline helps, but it’s not always enough.
In practice, you often need at least one 32-bit host instance. BizTalk does not support some components on 64-bit host instances. For example, FTP adapter, POP3 adapter, and MIME Decoder cannot run on 64-bit host instances. (https://docs.microsoft.com/en-us/biztalk/core/biztalk-server-64-bit-support2).
Recommended host layout (example)
We can define that one of the best practices for hosts and host instances is the following:
- BizTalkServerTrackingHost: A BizTalk Host that hosts tracking is responsible for moving the DTA and BAM tracking data from the MessageBox database to the BizTalk Tracking (DTA) and BAM Primary Import databases.
- BizTalkServerReceiveHost: This host will be responsible for processing messages after they are picked up in a receive location.
- BizTalkServerReceive32Host: has the same goal as the previous; however, this must have the 32-bits only option selected so that we can run the 32-bit adapters.
- BizTalkServerSendHost: This host will be responsible for processing messages before they are sent out to the send port.
- BizTalkServerSend32Host: has the same goal as the previous; however, this must have the 32-bits only option selected so that we can run the 32-bit adapters.
- BizTalkServerApplication: This host will be responsible for processing messages based on the instructions in orchestrations that need to run in 32-bit.
- BizTalkServerApplication64Host: This host will be responsible for processing messages based on the instructions in all or most common orchestrations.
Note: You can create other Application Host if you want to separate process base in some application logic.
Scripts and automation
You can read more about this topic in more detail in my previous post: PowerShell to Configure BizTalk Server Host and Host Instances according to some of the Best Practices.
You can find a simple script to configure Host, Host Instances, and Adapter Handlers described earlier in this post, optimized for BizTalk Server 2013 R2 (and also 2013), in GitHub:
Power Mode
The different performance states are dynamically managed by Windows in conjunction with hardware and platform firmware to respond to varying workload requirements. The 3 default power plans exposed by Windows provide varying trade-offs between performance and power consumption. For example, if the High-Performance power plan is selected, Windows places the system in the highest performance state and disables the dynamic scaling of performance in response to varying workload levels. Therefore, special care should be taken before setting the power plan to High Performance, as this can increase power consumption unnecessarily when the system is underutilized.
In some cases, you may experience degraded overall performance on a machine when running with the default (Balanced) power plan. The issue may occur irrespective of the platform and may be exhibited on both native and virtual environments. The degraded performance may increase the average response time for some tasks and cause performance issues with CPU-intensive applications
To change a power plan:
- Press the Windows key to switch to the Start screen, type Power Options, and click on the Power Options option from the Search menu.

- From the power plan page, choose the High-Performance option.

- Close the Power Option window.
Consider setting the ‘text in row’ table option to boost BizTalk Server Performance
SQL Server provides a table option called text in a row to declare that the contents of the fields of type text, ntext, or image data whose dimensions are smaller than those of a data page (8Kb) must be stored in a data row. By setting this option on BizTalkMsgBoxDb tables (Parts table, Spool table, and DynamicStateInfo Tables), you can increase message throughput when working with small messages that have a small context and orchestrations that have a small persistence size. This makes reading and writing the in-row strings about as fast as reading or writing limited-size varchar, nvarchar, or varbinary strings. Similarly, when the values are stored off-row, the Database Engine incurs an additional page read or write.
How to exploit the Text in Row table option in BizTalk Server
The following section explains how and when to apply the text in row table option to boost BizTalk performance.
- Parts Table: When the message size is smaller than the dimensions of a data page that is 8kb, applying the text in row table option on the Parts table can lead to BizTalk Server performance improvement.
- Spool Table: When the average size of the message context is less than 8 kb, enabling the text in row table option on the Spool table helps you reduce the number of accesses when reading messages from the MessageBox along with their context. To apply this option to the Spool table, you must eliminate unnecessary context properties and distinguished fields to reduce the size of the message context to less than 8 Kb.
- DynamicStateInfo Tables: These tables, one for each host, contain a field of type image called imgData that contains binary-serialized orchestration state when they encounter a persistence point during their execution. When the internal state of orchestrations within a host HostA is so small that its size once serialized is less than 8 kb, the text in row technique can successfully be applied to the DynamicStateInfo_HostA table. Therefore, we recommend that you keep the internal state of orchestrations as small as possible. This technique can significantly reduce the time that is spent by the XLANG Engine to serialize, persist, deserialize, and restore the internal state of orchestration in the case of a persistence point.
See more about this topic in the following resources:
- Post-Configuration Database Optimizations
- Microsoft BizTalk Server 2013 Performance Optimization Guide
You can use the following settings sample in your environment:
- EXEC sp_tableoption N’Spool’, ‘text in row’, ‘6000’
- EXEC sp_tableoption N’Parts’, ‘text in row’, ‘6000’
Related links
- BizTalk Server 2013 R2: Installation and Configuration – Important considerations before set up the server (Part 1)
- BizTalk Server 2013 R2: Installation and Configuration – Enable Internet Information Services (Part 2)
- BizTalk Server 2013 R2: Installation and Configuration – Install Windows Identity Foundation (WIF) (Part 3)
- BizTalk Server 2013 R2: Installation and Configuration – Install and configure SMTP Server Feature (Part 4)
- BizTalk Server 2013 R2: Installation and Configuration – Install Microsoft Office Excel 2013 (Part 5)
- BizTalk Server 2013 R2: Installation and Configuration – Install Visual Studio 2013 (Part 6)
- BizTalk Server 2013 R2: Installation and Configuration – Install SQL Server 2014 (Part 7)
- BizTalk Server 2013 R2: Installation and Configuration – Configure SQL Server Database Mail feature (Part 8)
- BizTalk Server 2013 R2: Installation and Configuration – Install and Configure BizTalk Server 2013 R2 (Part 9)
- BizTalk Server 2013 R2: Installation and Configuration – Configure SQL Server Network Configuration protocols (Part 10)
- BizTalk Server 2013 R2: Installation and Configuration – Validate Mail account used by BizTalk to send BAM Alerts (Part 11)
- BizTalk Server 2013 R2: Installation and Configuration – Installing BizTalk Adapter Pack (Part 12)
- BizTalk Server 2013 R2: Installation and Configuration – Install and Configure Microsoft UDDI Services (Part 13)
- BizTalk Server 2013 R2: Installation and Configuration – Install and Configure the Microsoft BizTalk ESB Toolkit (Part 14)
- BizTalk Server 2013 R2: Installation and Configuration – Configure BizTalk Server SQL Jobs (Part 15)
- BizTalk Server 2013 R2: Installation and Configuration – Optimize the BizTalk Server 2013 R2 environment (Part 16)
- BizTalk Server 2013 R2: Installation and Configuration – Optimize the BizTalk Server 2013 R2 environment (Part 17)
- BizTalk Server 2013 R2: Installation and Configuration – Install additional Developer tools (Part 19)
Hope you find this helpful! If you liked the content or found it useful and would like to support me in writing more, consider buying (or helping to buy) a Star Wars Lego set for my son.
Below is a script that will enable text-in-row , remember that if you create a new host you need to run the script again if you want that host to be able to use text-in-row.
USE BizTalkMsgBoxDb
DECLARE @tablename VARCHAR(512)
DECLARE @InRowCount INT
DECLARE dbcursor CURSOR FOR
SELECT table_name FROM information_schema.tables where table_name like ‘%DynamicStateInfo%’ or table_name = ‘Parts’ or table_name = ‘Spool’
OPEN dbcursor
FETCH NEXT FROM dbcursor INTO @tablename
WHILE @@FETCH_STATUS = 0
BEGIN
SET @InRowCount = OBJECTPROPERTY (OBJECT_ID(@tablename), ‘TableTextInRowLimit’ )
IF (@InRowCount = 0)
BEGIN
EXEC sp_tableoption @tablename, ‘text in row’, ‘6000’
select @tablename , OBJECTPROPERTY (OBJECT_ID(@tablename), ‘TableTextInRowLimit’ )
END
FETCH NEXT FROM dbcursor INTO @tablename
END
SELECT count(table_name) AS ‘Number of tables with Text-In-Row enabled’ FROM information_schema.tables where table_name like ‘%DynamicStateInfo%’ or table_name = ‘Parts’ or table_name = ‘Spool’
SELECT table_name AS ‘Tables with Text-In-Row enabled’ FROM information_schema.tables where table_name like ‘%DynamicStateInfo%’ or table_name = ‘Parts’ or table_name = ‘Spool’
Awesome feedback, thanks Jimmy