diff --git a/apps/fsearch/fsearch.cpp b/apps/fsearch/fsearch.cpp
index 8a233e219925bc52b0082f7b01eee1363e73b5da..58d7183c501f50c7a0090e060ac2b22cdb1bdac2 100644
--- a/apps/fsearch/fsearch.cpp
+++ b/apps/fsearch/fsearch.cpp
@@ -29,6 +29,7 @@ namespace po = boost::program_options;
 static const char* needle;
 static size_t needle_len;
 
+static emper::Semaphore* concurrent_open;
 static emper::Semaphore* max_fibers;
 static emper::Semaphore* max_searching;
 static emper::Semaphore* max_walking;
@@ -38,10 +39,12 @@ static emper::lib::ShardedFileBuffer* outBuf;
 static enum emper::StealingMode stealingMode;
 
 void search(const std::string& path) {
+	if (concurrent_open) concurrent_open->acquire();
 	int fd = emper::io::openAndWait(path.c_str(), O_RDONLY);
-	if (fd < 0) {
+	if (unlikely(fd < 0)) {
 		DIE_MSG_ERRNO("open of " << path << " failed");
 	}
+	if (concurrent_open) concurrent_open->release();
 
 	std::array<char, EMPER_RIPGREP_BUFSIZE> buf;
 
@@ -55,7 +58,7 @@ void search(const std::string& path) {
 		bytes_read = emper::io::readFileAndWait(fd, buf.data(), buf.size(), -1);
 	}
 
-	if (bytes_read < 0) {
+	if (unlikely(bytes_read < 0)) {
 		DIE_MSG_ERRNO("read of " << path << " failed");
 	}
 
@@ -94,6 +97,11 @@ static auto fssearch(const po::variables_map& vm) -> int {
 	needle = needleStr.c_str();
 	needle_len = needleStr.length();
 
+	if (vm.count("concurrent-open")) {
+		unsigned int concurrentOpenCount = vm["concurrent-open"].as<unsigned int>();
+		concurrent_open = new emper::Semaphore(concurrentOpenCount);
+	}
+
 	if (vm.count("max-fibers")) {
 		unsigned int maxFibersCount = vm["max-fibers"].as<unsigned int>();
 		max_fibers = max_searching = max_walking = new emper::Semaphore(maxFibersCount);
@@ -125,6 +133,7 @@ static auto fssearch(const po::variables_map& vm) -> int {
 
 	runtime.waitUntilFinished();
 
+	delete concurrent_open;
 	if (max_searching == max_walking)
 		delete max_fibers;
 	else {
@@ -144,6 +153,7 @@ auto main(int argc, char* argv[]) -> int {
 		("max-fibers", po::value<unsigned int>(), "Maximum number of fibers")
 		("max-searchers", po::value<unsigned int>(), "Maximum number of file searching fibers")
 		("max-walkers", po::value<unsigned int>(), "Maximum number of directory walking fibers")
+		("concurrent-open", po::value<unsigned int>(), "Maximum number of fibers calling open")
 		("stealing-mode", po::value<enum emper::StealingMode>(&stealingMode)->default_value(emper::StealingMode::child), "Stealing mode to use, either 'child' or 'continuation'")
 		;
 	// clang-format on