The Windows NT printing subsystem is one NT component you can teach a few new tricks. NT has a sophisticated client/server printing model that can use server resources to maximize performance while minimizing the administrative and system resource burdens on the client. In addition, NT includes flexible and powerful features for sharing network and local printer resources. This functionality lets you browse for available printers, make direct connections to shared NT printers (i.e., local printer drivers are not required), and maintain printing support for all supported NT hardware platforms, UNIX systems, Macintosh clients, and NetWare network clients. In this article, I'll examine a few of the configuration options you can manipulate to improve local and network printing performance.

What Is Fast, Anyway?
With printer performance, the first question to ask is, "What defines fast?" For example, does fast mean a speedy return to the application, a maximized data throughput stream to the printer, or a print server that's operating at maximum efficiency? The answer determines which adjustments you'll want to make on your system. I'll describe the ramifications of each modification and what type of performance improvement each adjustment helps you to achieve.

When you use the Printer folder to modify a printer's configuration, take note of the Scheduling tab of a printer's Properties dialog box, which Screen 1, page 162, shows. This tab provides several options that can affect printing performance: Priority, Spool print documents so program finishes printing faster, Print directly to the printer, and Print spooled documents first.

The Priority slider sets the default priority for documents you send to the printer (i.e., the base priority level each document starts out with). The default setting is 1 (lowest priority), although you can increase this number and then decrease the print priorities of individual jobs. One approach is to create a common-use printer with the default setting of 1 and then create a separate high-priority printer that prints to the same printing device but has a higher priority setting. This configuration is useful for high-priority print jobs when you're sharing a printer or when key personnel require faster access to a printer.

The Spool print documents so program finishes printing faster option instructs NT to spool printed documents to disk where it despools them to the printer. This option provides the quickest return of application control to the user and doesn't negatively impact performance. When you select this option, you'll see two suboptions. The first option, Start printing after last page is spooled, waits until a job completely spools to disk before sending it to the printer. The second option, Start printing immediately, begins despooling a print job immediately after the job begins queuing. I prefer the latter option because it provides a quick return of application control and the fastest printing of documents.

You might not want to use the Start printing immediately spooling option in a networked environment where many users print from programs that take a long time to generate each page of output (e.g., a CAD or 3-D graphics application). This situation can result in in- efficient printer utilization and long waiting periods, especially with large print jobs. The printer becomes tied up waiting for the application to spool each page, because it will have begun printing immediately after the first page was spooled. At this point, the printer will wait for the application to generate each additional job rather than just spool data to the printer that's ready for printing. To maximize efficiency, choose Start printing after last page is spooled, which ensures the entire print job is available to the printer and is printed without waiting for the application. However, the printing application will remain unavailable until the last job spools to the printer.

An alternative to the Spool print documents so program finishes printing faster option is the Print directly to the printer option. This option instructs NT to send documents directly to the printer rather than queuing them to a disk file. I don't recommend this option in most environments because it can significantly delay the return of application control after you send a print job. However, if you want to ensure the fastest possible time-to-output and are willing to sacrifice the ability to continue using the system while the print job is in progress, you might consider enabling this option.

The Print spooled documents first option instructs the NT print spooler to favor documents that have finished spooling over those that are still spooling, even if the completed documents have a lower print priority than the spooling documents. If no documents are finished spooling, the spooler favors large spooling documents over small ones. This option provides the best overall printer efficiency, and I generally recommend that you leave it selected. When you disable this option, the print spooler prioritizes document printing based on print priority.

In most environments, selecting the Start printing immediately and Print spooled documents first options will ensure that documents print as quickly as possible to your printer and maximize the printer's overall efficiency. To determine which options are best, consider whether you require the ability to continue using the system during print jobs, whether the printer is shared on a LAN, and the length and page generation time of the print jobs users typically send to the printer.

Giving Print Job Priorities a Boost
In addition to letting you configure printers, the Printers folder lets you view the current print queue and manage documents in the queue. The owner of a printer, or anyone with the NT Manage Documents privilege on the printer, can change the priority of a queued job. To do so, right-click the job's listing in the queue, and choose Properties from the pop-up menu that appears.

In the Properties dialog box for the print job, you can move the Priority slider bar to the right to increase the job's priority in the queue. The print job priorities range from 1 to 99, where 1 is the default priority NT assignes to all jobs. By increasing a job's priority in a backlogged print queue, you can advance a job's position in the queue to print more quickly. Screen 2 shows an example of using the document Properties dialog box to change the priority of a queued document.

You can change print priorities on a document-by-document basis with this method, or you can change the default priority assigned to all documents from a particular printer. For example, you can set the priority for the boss' printer higher for a shared network printing device so that the boss' jobs always print ahead of other jobs.

To set the default priority for all jobs printed to a particular printer, open the printer's Properties window in the Printers folder, and click the Scheduling tab. In this tab, which Screen 1 shows, you'll see the same slider bar that appears in a document's Properties dialog box, except that the priority set here affects all new documents printed using this printer.

To use this option effectively, you need to create a local printer for the user receiving the higher priority print jobs and point this printer to the network location (Uniform Naming Convention--UNC--name) of the shared printing device. Otherwise, if you install the printer using the Network printer server option of the Add Printer wizard, any changes you make to the default job priority level will be the same for all machines sharing the printer.

You can also implement this solution by creating multiple printers in the printers folder, all of which point to the same physical printing device. The advantage of this method is you don't have to use a locally created printer on the client workstation. If you assign different default document priorities and group permissions to each printer, you can control who uses the low-priority version of the printer and who uses the high-priority version. Because high-priority jobs will always print before low-priority ones (except those that are already printing), this configuration accomplishes the same feat as my previous example. In addition, this solution can scale as you add more high-priority printer users to the network.

Creating Printer Pools
One of NT's interesting printing features, and one of the best features for optimizing overall print performance, is the capability to create a special type of printer known as a printer pool. A printer pool is one virtual printer that you associate with multiple physical printing devices, each of which is connected to a different logical (network or local) port. Use this setup to create a round-robin arrangement for a heavily loaded print destination. When you've defined a printer pool, NT can automatically spool waiting documents to the next available printing device rather than queuing all jobs to one printing device.

When you're creating printer pools, all printing devices in the pool should be identical. At the very least, all the member printing devices must be able to emulate the same type of print device (i.e., they can all use the same printer driver). When you send print jobs to this printer, NT routes the job to the first available print device. This configuration makes printing much faster because the queue is not stuck waiting for one printing device for despooling jobs. (For information about creating printer pools in NT, see Michael D. Reilly, "Printing With Windows NT," July 1997.)

Supercharging the NT Spooler
The NT Spooler service is responsible for much of the work during the NT printing process. In essence, the NT Spooler service is a print job scheduler and is part of a machine's local Print Provider service. The Spooler service has four primary responsibilities relating to the printing process: tracking what print jobs are going to which printers, tracking which ports connect to which printers, routing print jobs to the correct ports, and prioritizing print jobs. NT uses a separate process thread for each printer port. A thread calls the NT Spooler service whenever the thread completes a job or when an external thread initiates a print job. You can adjust the NT Spooler service to enhance its performance and ensure that it runs optimally.

Boosting spooler thread priorities.
Because the NT Spooler service is an application running on an NT computer, its worker threads receive a default thread priority, which is comparable to that of other noncritical system services. However, you can boost print server performance by increasing the default thread priority assigned to the NT Spooler service and its various components.

This adjustment might be helpful, for example, on a heavily taxed or dedicated NT print server that handles several jobs every day. In these situations, you can adjust the print-related Registry values to help print server speed and efficiency. You'll find the Registry values at HKEY_ LOCAL_MACHINE\SYSTEM\Current ControlSet\Control\Print. Screen 3 shows this Registry subkey and its default values. The values that we're primarily concerned with are the PortThreadPriority, PriorityClass, SpoolerPriority, SchedulerThreadPriority, FastPrintThrottleTimeout, FastPrintWaitTimeout, FastPrint- SlowDownThreshold, and NetPrinterDecayPeriod values. Each value can affect some aspect of print (or print browser) performance. Let's look at these values, their default data, and their possible data ranges.

PortThreadPriority.
Each defined printer port in NT has an associated thread that sends data to the port. This REG_DWORD value's data defines the priority used for these port threads. The value takes ­1, 0, or 1, which correspond to THREAD_PRIORITY_ BELOW_NORMAL, THREAD_PRIORITY_ NORMAL, and THREAD_PRIORITY_ ABOVE_NORMAL. In NT 4.0, these values represent priorities of 7, 8, and 9, on either a workstation or server. Table 1, page 166, includes descriptions and numerical equivalents for each thread priority.

PriorityClass.
This REG_DWORD value, which is used only in NT 3.5x, defines the priority class (i.e., the associated thread priority of the NT Spooler service). The default setting is 0, which means that NT is to use the default priority (THREAD_PRIORITY_NORMAL). In NT 4.0, the SpoolerPriority value replaced this value.

SpoolerPriority.
This NT 4.0 REG_ DWORD value replaces the PriorityClass value and sets the priority class for the print spooler. This value doesn't automatically appear in the Registry, and you have to add it manually to change the data.

By default, the print spooler is set to NORMAL_PRIORITY_CLASS. Valid settings for this value are IDLE_ PRIORITY_CLASS, NORMAL_PRIORITY_ CLASS, and HIGH_PRIORITY_CLASS (NT ignores any other settings). Table 1 provides descriptions and numerical equivalents for each priority class.

SchedulerThreadPriority.
This REG_ DWORD) value sets the priority of the scheduler thread, which is responsible for assigning print jobs to ports. The default setting for this value is 0, meaning that NT is to use a normal thread priority. Valid settings for this value are 0 (Normal), 1 (Above Normal), and 0xFFFFFFFF (Below Normal; note this number is hexadecimal and not a string value). You can modify this Registry value with the System Policy Editor (SPE) utility, or you can place it within a global System Policy file (NTConfig.pol)--it is part of the default .adm templates that the SPE utility includes.

FastPrintThrottleTimeout.
When you enable the Start printing immediately option in the Scheduling tab of a printer's Properties dialog box, some printers pause if they don't receive data for a timeout period (time varies depending on type of printer). To counteract this situation, the spooler throttles back on data sent to the printer after the number of milliseconds represented by the FastPrintSlowDownThreshold value have passed. At that point, 1 byte of data is sent to the printer per period represented by FastPrintThrottleTimeout until the amount of time defined by FastPrintSlowDownTheshold value has passed. You enter this
REG_DWORD value in milliseconds (ms), and the default data is 2000ms (2 seconds).

FastPrintWaitTimeout.
When you enable the Start printing immediately option in the Scheduling tab of a printer's Properties dialog box, the port thread must be synchronized with the application spooling the print job. The FastPrintWaitTimeout value determines how long the port thread will wait before giving up, pausing the current print job, and moving to the next print job. You enter this REG_DWORD value in milliseconds, and the default setting is 24,000ms (24 seconds).

FastPrintSlowDownThreshold.
NT uses this REG_DWORD value with the FastPrintThrottleTimeout value to determine at what point the spooler is to begin throttling back the data the operating system (OS) sends to the printer (to maintain a continuous flow of data to the printer and not trigger a printer timeout). The default setting is the FastPrintWaitTimeout value divided by the FastPrintThrottleTimeout value, but you can manually set this value (enter the value in milliseconds).

NetPrinterDecayPeriod.
This REG_ DWORD value specifies how long NT is to cache a network printer for a local machine's client browser. The cache presents a list of network shared printers when you browse for available printers. The range is in milliseconds, and the default setting is 3,600,000ms (1 hour).

When modifying these Registry values, use the thread priorities and priority classes described in Table 1 as a guideline. As with any type of Registry modification, make any changes in small increments and benchmark them along the way, using a standard test to determine their effectiveness. Modifications to these Registry values will not produce significant benefits except on the busiest print servers serving several printing devices. Also, increasing the priorities of print-related threads on NT servers that aren't dedicated to print serving (i.e., servers being used as file or application servers) will deprioritize the access of other process threads.

Optimizing the print spooler file.
The location of the default spooler file NT uses for printer spooling can increase performance. NT spools print jobs to disk before printing them (as long as the printer's print spooling option is turned on). By default, NT spools jobs to the %systemroot%\system32\ spool\printers folder. However, on servers that experience a heavy disk load on the boot partition (where the %systemroot% folder is located) due to application and paging file activity, disk spooling activities might be slowed because of disk contention. This situation can adversely affect overall printing performance because the disk spooling thread must wait for other system activities before receiving disk time to write spool data.

To alleviate this problem, consider moving the default spool file location on a print server to an alternative drive. To do so, open the Printers folder and select File, Print Server Properties. Next, select the Advanced tab of the Properties dialog box. To move the spool location, change the value listed in the Spool Folder option to an alternative folder, as Screen 4, page 168, shows. (Before doing so, make sure that this folder exists and that all users who will print to this machine have at least Change permissions on the folder if it is on an NTFS partition.)

You can change the Spool Folder location in NT 3.x, but you must use a Registry editor to edit the Registry directly. The value for the default Spool Folder for all printers is in HKEY_ LOCAL_MACHINE\SYSTEM\Current ControlSet\Control\Printers (which is the same Registry location under NT 4.0). The value to modify is DefaultSpoolDirectory of type REG_SZ. The default setting is %systemroot%\system32\spool\ printers, but any valid directory pathname is acceptable.

You can modify the DefaultSpoolDirectory value by editing the associated string data and replacing it with the name of an alternative directory for printer spool files. Again, be sure that any users who will be printing to that machine have at least Change permissions (if on an NTFS partition) and that the folder already exists.

Tuning Network Print Browsing
When you share a printer on a networked NT computer, the NT Spooler service issues a broadcast message to all other print servers on the network about the existence of the new printer share. The other print servers receive notice of the new printer share and add it to their printer browse lists. In addition, all print servers automatically rebroadcast their entire list of available print servers and shares every 10 minutes to all other print servers on the network. This activity can cause excessive traffic on large networks with many active print servers.

To reduce this traffic, you can implement several Registry modifications that relate to print browsing. These entries are in the same Registry subkey we examined earlier in regard to print browsing: HKEY_LOCAL_MACHINE\SYSTEM\ CurrentControlSet\Control\Print. Several values within this Registry subkey relate to print browsing.

DisableServerThread.
You can set this REG_DWORD value, which has a default setting of 1 (enabled), to 0 to disable the print browser thread (which notifies other print servers of the shared printers on that computer).

Be aware that when you disable the print browser thread by changing the DisableServerThread value, you will prevent other print servers and clients on the network from seeing the printers shared on that computer via the Network Neighborhood. You'll need to make any connections to shared printers on the machine manually (via UNC names) rather than via the Network Neighborhood. When you disable this thread or reduce its announcement frequency, you can significantly reduce network traffic on a large network containing several print servers (print servers includes any Microsoft Windows-based machine sharing a printer on the network, not just NT server computers). Finally, note that you can also set this particular Registry value via System Policy Editor (SPE), and it is part of the default set of system policies included with SPE. You might find this method more convenient for configuring the entry for multiple NT systems on a network.

ServerThreadTimeout.
This REG_ DWORD value specifies the amount of time that the server thread waits before sending announcements about available printers on the machine. This value is in milliseconds, and the default setting is 36,000ms (36 seconds). Setting this number higher reduces network traffic by reducing the frequency of print browser announcements.

NetPrinterDecayPeriod.
This REG_ DWORD value specifies the amount of time the machine is to cache print server and share lists obtained from print servers on the network. If you adjust the ServerThreadTimeout value, set a longer decay period value to correspond to the longer announcement intervals. This value is in milliseconds, and the default setting is 3,600,000ms (1 hour).

RefreshTimesPerDecayPeriod.
This REG_DWORD value specifies the number of times per decay period that the machine is to refresh the browse lists of browse masters and backup browsers. The default setting is 2 (times per hour, the default decay period) and can range from 1 to 5.

Improving Print Server Performance
A final Registry modification that can improve a print server's network performance is to increase the Server service's network request buffer. This change can help network printing performance because NT handles all network print jobs from remote clients via the Server service.

The SizReqBuf value under the HKEY_LOCAL_MACHINE\SYSTEM\ CurrentControlSet\Services\LanMan Server\Parameters Registry key defines the server's request buffer size. The value SizReqBuf is of data type REG_ DWORD. The default setting is 4356 bytes and can range from 512 bytes to 65536 bytes.

If the value doesn't appear, you can add it using the Registry editor's Add Value option. Experiment by increasing this value in 64-byte increments to see whether you realize additional printer performance. (Reboot the system each time you change the value to be sure the changes take effect.)

Ready to Print
Now you're ready to test these strategies for improving printing performance under NT. Always test any optimiza-tions (especially those involving modifications to the Registry) on a non-production machine that won't affect your network or users. Only after you establish that you can safely implement the modification in your environment should you deploy it on production machines.