Increase RAM for ElasticSearch for TFS Search

If you are experiencing slow search in TFS with the new Search functionality based on ElasticSearch a typical suggestion is to give more RAM to the machine where ES is installed. Clearly you should use HQ or other tools to really pin down the root cause but most of the time the problem is not enough RAM, or slow disks. The second cause can be easily solved moving data to an SSD disk, but giving more RAM to the machine, usually gives more space for OS File cache and can solve even the problem of slow disk.

ElasticSearch greatly benefit from high amount of RAM, both for query cache and for operating system cache of Memory Mapped Files

There are really lots of resources in internet that explain perfectly how ElasticSearch uses memory and how you can fine tune memory usage, but I want to start with a quick suggestion for all people that absolutely does not know ES, because one typical mistake is giving to ES machine more RAM but leaving ES settings unaltered.

Suppose I have my dedicated search machine with 4GB of RAM, the installation script of TFS configured ES instance to use a fixed memory HEAP of half of the available RAM. This is the most typical settings that works well in most of the situations. Half the memory is dedicated to Java Heap and gives ES space for caching queries, while the other 2 GB of RAM will be used by operating system to cache File access and for standard OS processes.

Now suppose that the index is really big and the response time starts to be slow, so you decided to upgrade search machine to 16 GB of RAM. What happens to ES?


Figure 1: Statistics on ES instance with HQ plugin shows that the instance is still using 2GB of heap.

From Figure 1 you can verify that ES is still using 2 GB of memory for the Heap, leaving 14 GB free for file system cache and OS. This is clearly not the perfect situation, because a better solution is to assign half the memory to java HEAP.

ElasticSearch has a dedicated settings for JAVA Heap usage, do not forget to change that setting if you change the amount of RAM available to the machine.

The amount of HEAP memory that ES uses is ruled by the ES_HEAP_SIZE environment variable, so you can simply change the value to 8G if you want ES to use 8 GB of Heap memory.


Figure 2: Elastic search uses an environment variable to set the amount of memory devoted to HEAP

But this is not enough, if you restart ElasticSearch windows service you will notice that ES still uses 1.9 GB of memory for the HEAP. The reason is: when you install ES as service, the script that install and configure the service will take the variable from the environment variable and copy it to startup script. This means that even if you change the value, the service will use the old value.

To verify this assumption, just stop the ElasticSearch service, go to ES installation folder and manually starts ElasticSearch.bat. Once the engine started, check with HQ to verify that ES is really using use 8GB of ram (Figure 2).


Figure 3: ES now uses the correct amount of RAM.

To solve this problem, open an administrator prompt in the bin directory of ElasticSearch, (you can find the location from the service as shown in previous post) and simply uninstall and reinstall the service. First remove the service with the service remove command, then immediately reinstall again with the service install command. Now start the service and verify that ES is using correctly 8GB of RAM.

When ElasticSearch is installed as a service, settings for Memory Heap Size are written to startup script, so you need to uninstall and reinstall the service again for ES_HEAP_SIZE to be taken in consideration

If you are interested in some more information about ES and RAM usage you can start reading some official article in ES site like:

I finish with a simple tip, ES does not love virtual machine dynamic memory (it uses a Fixed HEAP size), thus it is better to give the machine a fixed amount of ram, and change HEAP size accordingly, instead of simply relying on Dynamic Memory. 

Gian Maria.

VSTS Package, packages failed to publish

I have a build that publishes nuget packages on MyGet, we decided to move packages to VSTS internal package management, so I simply added another Build Task that pushes packages to VSTS internal feed. Sadly enough I got a really generic error

Error: An unexpected error occurred while trying to push the package with VstsNuGetPush.exe.
Packages failed to publish

Those two errors does not gives me real information on what went wrong, but looking in the whole log, I verified that the error happens when the task was trying to publish symbols packages (2).


Figure 1: Complete error log

It turns out that VSTS Package management is not still capable of publishing symbols package and this generates the error.

To solve this problem you can avoid generating symbols package, or you can simply avoid pushing them to VSTS feed. In the future VSTS feeds will probably supports symbols package and this problem will be gone.

In the meanwhile we have a issue on GitHub where we asked to the team for a much clearer error message, that can immediately point out the problem during the push.

Gian Maria.

Monitor TFS Search data Usage

In previous post I’ve explained how to move searches component in a different machine in a TFS 2018 installation, now it is time to understand how to monitor that instance.

First of all you should monitor the folder that physically contains data, in my installation is C:\tfs\ESDATA (it is a parameter you choose when you configure the Search Server with Configure-TFSSearch.ps1 -Operation install PowerShell script). Data folder should be placed on a fast disk, usually SSD are the best choice. If the SSD will ever fail, you can always restart ES with empty data folder and use scripts to force TFS to reindex everything.

Data in ElasticSearch can be wiped away without problem, like WareHouse database, its content can always be restored.

If you want to have a better idea on what is happening to your search instance you can install plugins to easy management. First step: connect to the machine where the Search Service is running and locate the folder where ElasticSearch was installed. A simple trick is checking corresponding Windows Service.


Figure 1: Locate ElasticSearch binaries from Windows Service

Now simply open a command prompt and change directory to the bin installation directory of ElasticSearch, from here you can install various plugin to simplify ES management, I usually starts with the HQ plugininstallable with the simple command

plugin install royrusso/elasticsearch-HQ/v2.0.3

You should check the correct version in HQ home site, version 2.0.3 is the latest version that works with ES 2.4.1, the version used by TFS Search Service. For this command to being able to run, the machine should have an internet connection and GitHub site should not be blocked.


Figure 1: HQ was correctly installed

Now you can just browse to http://localhost:9200/_plugin/HQ to open the web interface of HQ plugin and connect to the actual instance.


Figure 3: HQ plugin up and running and ready to be connected to local instance of ES.


Figure 4: Home page of HQ, where you can find the total size used by the server (1) and you can also have some Node Diagnostics (2)

From Node Diagnostics tool you can find if some statistics are not good, in my example I have search server in a server with slow disk and query time is sub-optimal. Usually ES is supposed to answer in less than 50 milliseconds, in my installation I have an average time of 660ms.


Figure 5: Statistics on search.

If you move the mouse over the number, it can give you some hint on the reason why the specific number is calculated and why is not considered to be good.


Figure 6: Help on the various number gives you an idea on what is wrong and how you could solve this.

If you are experienced slow search, there are many factors that can impact the instance of ElasticSearch and using a good plugin for diagnose the real root cause of the problem is usually the best approach.

I suggest you to navigate in HQ interface to familiarize with the various information it can gives to you, especially clicking on the name of a single node (there is only one node in my installation), you can get some interesting data on that single node, especially on RAM usage.


Figure7: Ram usage of a single node.

There are lots of other plugins that can show lots of useful information about your ElasticSearch instance, the installation is similar to HQ and you can install and use them with very few clicks.

Gian Maria.

TFS 2018 search components in different server

When it is time to design topology of a TFS installation, for small team the single server is usually the best choice in term of licensing (one one Windows Server license is  needed) and simplicity of maintenance. Traditionally the only problem that can occur is: some component (especially the Analysis and Reporting services) starts to slow down the machine if the amount of data starts to become consistent.

Single machine TFS installation is probably the best choice for small teams..

The usual solution is moving Analysis Service, cube and Warehouse database on a different server. With such a configuration if the analysis service has a spike in CPU, Disk or Memory usage, the main machine with operational DB and AT continue to work with standard performance. The trick is leaving the core services in a server that is not overloaded with other tasks, this is the reason why running a build agent in TFS machine is usually a bad idea.

With TFS 2017 a new search component is introduced, based on ElasticSearch. ES is de facto the most used and most advanced Search Engine on the market, but it tends to eat CPU RAM and Disk if the workload is big. The suggestion is to start configuring search on the very same machine with AT and DB (Single server installation) and move search components if you start to notice that ES uses too many RAM or is using too much CPU when it is indexing data. Moving search components on another machine is a really simple process.

First of all you need to remove the search feature, using the remove feature wizard as shown in Figure 1 (select the first node in administration console to find the Remove Feature Link)


Figure 1: Remove feature from TFS instance

Now you should choose to remove the search feature.


Figure 2: Removing the Search Service functionality

After the wizard finished, you should go to the folder C:\Program Files\Microsoft Team Foundation Server 2018\Search\zip and with powershell run the command

Configure-TFSSearch.ps1 -Operation remove

to completely remove Elastic Search from your TFS instance.

Do not forget to use Configure-TFSSEarch PowerShell script to completely remove any trace of Elastic Search from the TFS machine

Now search component is not working anymore, if you issue a search you should get a message like shown in Figure 3:


Figure 3: Search component is not operational anymore.

At this point you open TFS administration console and start the wizard to configure the search, but this time, instead of configuring everything on the current machine, you will choose to use an existing Search Service.


Figure 4: Use an existing search service instead of install locally the search service

If you see in Figure 4, the instructions to install search service on another computer are really simple, you need to click the “search service package” link in the wizard to open a local folder that contains everything to setup ElasticSearch and the search service. Just copy content of that folder on another machine, install java and set the JAVA_HOME environment variable and you are ready to install Search Service.

You can find a README.txt file that explain how to configure the search service, just open a PowerShell console and then run the command

Configure-TFSSearch.ps1 -Operation install -TFSSearchInstallPath C:\ES -TFSSearchIndexPath C:\ESDATA

Please change the two folder if you want to change the location of ElasticSearch binary and ElasticSearch data. After the script ran without any error, it is time to verify that ElasticSearch is correctly installed and started. As usual, please create a DNS entry to avoid using the real name of the machine where you installed the service. In my installation I’ve configured the name tfssearch.cyberpunk.local to point to the real machine where I configured search services. Just open a browser and issue a request to http://tfssearch.cyberpunk.local:9200


Figure 5: Try to access local instance of ElasticSearch using DNS name

Please pay attention at firewall configuration, because ElasticSearch has no security in base installation and everyone can mess up and read data just browsing in port 9200

Now you should open your firewall to allow connection to port 9200 from every machine where an Application Tier is running. In my situation the machine with TFS installation has IP number Remember that Elastic Search has NO Authentication (it is a module that is not free, called shield), thus it is really better to allow connections only from the TFS machine. All you need to do is creating a rule to open port 9200, but allowing connection only from the IP of the TFS machines.


Figure 6: Firewall configuration, the machine with the search service opens port 9200 only from the IP of the TFS machine.

Now remote desktop to TFS machine, and verify that you are indeed able to browse http://tfssearch.cyberpunk.local:9200, this confirm that configuration of the firewall allows TFS to contact the search service. Then try to access the very same address from another computer in the network and verify that it CANNOT access ElasticSearch instance. This guarantees that no one in the network can access Elastic Search directly and mess up with its data.

Now you can proceed with the Configuration Wizard in TFS instance, specifying the address of your new Search Server


Figure 7: Configure new search service in TFS.

Proceed and finish the wizard. At the end TFS machine will re-index all the data in the new search server, just wait some minutes and you will be able to use again search, but now all Search Components are on a dedicated server.

Gian Maria.

Configure Visual Studio 2017 15.5 for pull –rebase

I’m a great fan of rebasing over merge and I’m convinced that the default pull should be a fetch and rebase, using fetch and merge only when it is really needed. Not having the option to configure a GUI to do a pull –rebase is a really annoying problem, that can be somewhat limited configuring pull.rebase git option to true, as explained in previous post. Actually, the lack of rebase on pull option makes me stop using the IDE.

To have a linear history in Git, always consider rebase over merge, especially for everyday pulls.

I’ve used this technique extensively with VS 2017, the only drawback is an error during pull because VS complains about “unknown merge result” since he was not able to find merge commit. Give this, I was always reluctant to suggest to customers, because it is not good having your IDE constantly show error at each pull.

After updating to 15.5 version I noticed that the error went away and the IDE correctly tells me that a pull with a rebase occurred. If I open the global or repository settings in Team Explorer I can found that now, finally, pull.rebase is supported.


Figure 1: Pull with rebase is now supported, as well as other interesting options.

Actually these are the basic settings of Git, if you configure the repository or globally the Rebase local branch when pulling, it will set pull.rebase to true, nothing more. The important aspect is that the IDE now honor the settings. Suppose you have one local commit and one remote commit like in Figure 2:


Figure 2: Classic situation where you have local commit and remote commits

Now if you simply press the pull command in the IDE, you will see that VS is correctly issuing a rebase. When everything is finished you are informed that indeed a rebase was done, the error went away.


Figure 3: Visual  Studio correctly rebased local branch on the remote branch.

With this latest addition I can confirm that Visual Studio is now a really interesting IDE to work with Git (even if, if you are experienced with Git, probably you will still stick in CommandLine most of your time).

P.s: Another nice addition is the support to prune after fetch and support to push –force. If you try to push a commit after an amend, instead of the standard error, you will be prompted with a  MessageBox that asks you if you really want to force the push.


Figure 4: MessageBox asking for a push force if needed.

If you are curious about why VS is using a –force-with-lease instead of a standard –force, please read this article. Basically it is a way to force the push if no one had pushed something else in the meanwhile. If you really need to force a push, like when you rebase a feature branch, you can always use commandline.

Gian Maria.