Get an Estimate Processing Time of USCIS Cases


The USCIS’s case progress lookup tool does not give you an estimate waiting time for the decision of your case. However, by sending thousands of queries to the USCIS website, we can estimate our waiting time base on other cases’ status.

I developed this small app for my personal use. If anyone else wants to use it feel free to do that. But be aware that if you send a large amount of query in a short time, you may be considered abusing the lookup tool, or even considered performing DoS attack against the gov, and you may get IP-banned or any further punishments. You have been warned.


Students under the F-1 visa usually apply for Optional Practical Training (OPT) to get work authorization from US Citizenship and Immigration Services (USCIS). When one application is received by the USCIS, they issue a receipt number. Using this receipt number to check one’s progress (here) is highly unsatisfying. The application usually takes up to 4 months to process. Until the work authorization is approved, students will only get a somewhat useless paragraph like this:

On November 16, 2017, we received your Form I-765, Application for Employment Authorization, Receipt Number YSC1890044628, and sent you the receipt notice that describes how we will process your case. Please follow the instructions in the notice.

And nothing more.

No estimated time. No queue information. No current status.

USCIS does a really bad job of keeping one updated on the progress of a case and in general how far along they are going with the entire year’s batch of students.

Predicting decision time

Fortunately, USCIS issues receipt numbers in chronological order, and they process their cases in a first-come-first-serve order. That means if we check other people’s case status, we will be able to get an estimated time of case decision:

  • If a huge proportion of people before me (and possibly after me) have their OPTs approved, I should have mine processed soon.
  • However, if people who submitted around my date are still waiting, I can expect to wait for a longer time.

However, doing so manually is a slow and tiring process. Instead, I can write a script to check the website for the 50,000 or so cases before and after my own number.

Python Version

Works. The Python version is the first thing I come up with.

EAD-AutoQuery> python
YSC1890008628 ,  I-765 ,  Request for Initial Evidence Was Mailed
YSC1890010628 ,        ,  Card Was Mailed To Me
YSC1890012628 ,  I-130 ,  Case Was Received

But soon I am tired of comparing the results in two files using the diff tool. I decided to create one with GUI. For practice purpose, I used Visual C#.NET.

C# Version

Abandoned. It can scrape from USCIS and dump interested data into an SQLite database.

I was working on this one until USCIS blocked my IP after about 2,000 queries.

It was reported to us that your IP address or internet gateway has been locked out for a select period of time. This is due to an unusually high rate of use.

Apparently, a (or actually, a dozen) proxy server is needed. I am not planning any budget for this small project. Thus, deploying the C# application on VPS is not an option. There are not many free route proxy server either, I do not trust those “free” proxies. So the only truly free solution seems to be those massive PHP hosting services available online. So I moved on to the PHP version.

JavaScript + PHP Proxy

Sweet combination. Works pretty well.

Thought about multi-thread PHP scraper. PHP is not suitable for multi-threading… at least not natively.

Use pure client-side AJAX…? Cross-Origin Resource Sharing will stop the browser fetching data from USCIS and that’s going to be a problem.

I end up using a PHP script from the same origin as a proxy to load the real page on different origin. This satisfies all the requirements.

After setting up scrape controlling conditions, JavaScript will initialize several AJAX threads.

When one AJAX query finishes, in its always call back, it starts a new AJAX to query the next case id in the queue. When a query is done, JS will extract interesting information, i.e.,

Form – which form did the case submit
Title – a summary of the current status
ActivityDate – date of last USCIS activity
Content – The full paragraph
QueryDate – current timestamp

Then use another AJAX to store them in my remote database. I used an API on my personal server.

This will cause CORS error though. But I don’t care. Interested data will be sent to whatever origin specified. CORS protection only kicks in when the browser tries to receive data. In my case, I do not even intend to get any result. Data is sent to my server, and that’s all I want.

Tested with 60,000 case IDs with 500 threads. Took almost three minutes to finish the scrape.

The 000webhost server IP was blocked after about 97,000 queries.

Will edit when IP was unblocked.



17 hours has passed and is still blocked.

Unblocked after 23 hrs.

Blocked again when I checked their processing status during the weekend. Why did I query on weekends… they are not going to update anything…

So, 92 days after they received my application, which is exactly on the predicted day, USCIS finally approved my application. Now my case status is updated to “New Card Is Being Produced”.

On day 95, the status is updated to “Card Was Mailed To Me”.

On day 98, I received my card. Finally, I can start my employment.



But be aware that if you send a large amount of query in a short time, you may be considered abusing the lookup tool, or even considered performing DoS attack against the gov, and you may get IP-banned or any further punishments. You have been warned.

Leave a Reply

Your email address will not be published. Required fields are marked *