Optimizing RDP Performance (xrdp): Lessons Learned with Ubuntu 22.04

Picture of Chris Beye

Chris Beye

Systems Architect @ Cisco Systems

Table of Contents


In the dynamic world of system engineering, the choice between proprietary and open-source software often hinges on practicality and expertise. I’m a big supporter of open-source solutions, recognizing their potential in the right scenarios. However, this preference isn’t without its challenges. Open-source systems demand a deeper understanding, requiring time and effort that might not always be available, especially when deep-diving into complicated configuration files.

Currently, I’m gearing up for an upcoming session at Cisco Live. This preparation includes setting up a shared environment for users. Traditionally, I’ve relied on a Windows Jumphost for user connections. But, as many of us have experienced, Windows struggles with handling multiple RDP sessions. The alternative? Setting up a Windows Server with a terminal server role – a task that I quickly discarded.

In search of efficiency, I turned to Ubuntu 22.04, installing and initiating XRDP. My anticipation for a smooth performance was met with a stark reality. The experience was frustratingly slow, challenging the practicality of this open-source solution in a user-shared environment.


After searching through various sites and wasting a couple of hours I got a workable solution and the user experience through RDP is okay. Below you will find the customizations:  

Display- and window- manager
  • Changing from Gnome to XFCE did make a huge difference but it was still far from perfect.
    In short, XFCE is a lightweight window manager which does exactly what I wanted. I don’t need any fancy styles or animations. 
  • Changing to a lightweight display manager (LightDM) helped also in getting a better experience.
    LightDM, created by Canonical, stands out for its lack of GNOME dependencies. This display manager is not only highly customizable but also notably lightweight, making it an ideal choice for Linux systems. Its release cycle aligns with Ubuntu’s, ensuring concurrent support within the same timeframe.

Isn’t that a bit confusing? What is a window and display manager?

  1. Display Manager:

    • Function: The display manager is the first graphical interface you interact with when starting your computer. It manages user sessions and handles user authentication (login screen).
    • Examples: LightDM, GDM (GNOME Display Manager).
    • Role in Ubuntu: It initializes the graphical environment, prompts for user credentials, and loads the user’s preferred desktop environment.
  2. Window Manager:

    • Function: Once logged in, the window manager takes over. It controls the look and feel of windows – their borders, title bars, resizing, dragging, and the controls for minimizing or closing.
    • Examples: XFCE, LXDE, OpenBox
    • Role in Ubuntu: The window manager is responsible for how applications appear and how you interact with them. It can be part of a desktop environment or operate standalone for a more minimal setup.

This makes sense to adjust for a better experience!

					sudo apt-get update
sudo apt-get install xfce4-session xfce4-goodies lightdm 
sudo dpkg-reconfigure lightdm

If you want a user to automatically load XFCE, place a text file called .xfce4-session in the home directory with the following content:

					$ cat .xsession
XRDP customazations

Let’s take a look at the xrdp service as there are some ways to optimize the performance. 

  1. tcp_nodelay=true

    • Purpose: This setting is related to TCP’s Nagle’s algorithm. When set to true, it disables Nagle’s algorithm, which means that packets are sent as soon as possible without waiting to fill up the full TCP segment. This can reduce latency in a network connection.
    • Effect: Useful in interactive applications like remote desktops, as it can make the connection feel more responsive.
  2. tcp_keepalive=true

    • Purpose: This parameter enables TCP keepalive feature. It ensures that the connection between the client and the server remains active even when there’s no data being transmitted.
    • Effect: Prevents the connection from being closed due to inactivity, which can be important in remote desktop sessions that might have periods of no user activity.
  3. tcp_send_buffer_bytes=4194304

    • Purpose: Sets the size of the TCP send buffer to 4,194,304 bytes (or 4 MB).
    • Effect: A larger send buffer can improve performance in high-latency networks by allowing more data to be “in flight” on the network. However, setting it too high can lead to inefficient use of bandwidth and increased memory usage.
  4. crypt_level=low

    • Purpose: This sets the encryption level for the RDP session. low means minimal encryption is used.
    • Effect: While this setting can improve performance because of lower computational overhead, it also makes the connection less secure. It’s typically not recommended for environments where security is a concern. This was the mosy significant tuning parameter!
  5. max_bpp=16

    • Purpose: Stands for “maximum bits per pixel” and is set to 16 in this case.
    • Effect: This limits the color depth of the remote session to 16 bits per pixel. Reducing color depth can decrease the amount of data sent over the network, improving performance, especially on slower connections. However, it also means lower color fidelity.

Please change the following values in the /etc/xrp/xrp.ini:

crypt_level = low
max_bpp = 16
  1. KillDisconnected=true

    • Purpose: This parameter determines the behavior of the XRDP server when a user’s session is disconnected.
    • Effect: Setting it to true means that the XRDP server will automatically terminate a session once it gets disconnected. This can be useful for freeing up system resources that would otherwise be occupied by inactive sessions.
  2. DisconnectedTimeLimit=0

    • Purpose: This parameter sets a time limit (in milliseconds) for how long a disconnected session is allowed to remain idle before it’s terminated.
    • Effect: Setting it to 0 effectively means that there is no time limit. The session will remain disconnected indefinitely until some other action or policy terminates it. This setting is particularly relevant when KillDisconnected is set to false, allowing disconnected sessions to persist for manual reconnection or administrative handling.

Please change the following values in the /etc/xrp/seman.ini:

User session changes

Disable the composition which is responsible for advanced graphical features like transparency, shadows, and animations.

					$ xfconf-query --channel=xfwm4 --property=/general/use_compositing --type=bool --set=false --create


I also had the annoying message “System program problem detected” after a login.  To disable this pop-up change the file as shown below.  

					$ sudo cat /etc/default/apport 
# set this to 0 to disable apport, or to 1 to enable it
# you can temporarily override this with
# sudo service apport start force_start=1


While open-source software offers flexibility, control, and cost-effectiveness, it also demands a deeper technical understanding and a readiness to tackle hands-on configuration challenges.

This experience serves as a reminder that in the realm of system engineering, especially when dealing with shared user environments, the choice between open-source and proprietary software isn’t just about preference, but also about practicality and efficiency. 

While out-of-the-box systems offer convenience and immediate functionality, they frequently require performance tuning to meet specific operational needs. This tuning is essential to optimize the system’s efficiency and ensure it aligns with the unique demands of its intended environment.

Still, one open issue is the creation of a default user profile. Everyone who logs in should get the same environment but that is a problem for the next article. 😜